Изучение модели вычислений операция-операнд”


Проблемы, которые необходимо решить на нейрокомпьютерах


Download 49.55 Kb.
bet4/5
Sana11.05.2023
Hajmi49.55 Kb.
#1453805
1   2   3   4   5
Bog'liq
Кампютер архитектураси практика 2

Проблемы, которые необходимо решить на нейрокомпьютерах.

Одной из главных проблем, которую можно решить с помощью нейрокомпьютеров, является задача распознавания образов. В этой практической работе мы рассмотрим пример использования нейронной сети для распознавания рукописных цифр.


Для начала, мы должны загрузить набор данных MNIST, который содержит 60 000 изображений рукописных цифр для обучения и 10 000 изображений для тестирования. Мы будем использовать библиотеку `OpenCV` для загрузки изображений.


```cpp
#include


#include

int main() {


// Load MNIST dataset
cv::Mat train_images = cv::imread("train-images-idx3-ubyte.gz", cv::IMREAD_UNCHANGED);
cv::Mat train_labels = cv::imread("train-labels-idx1-ubyte.gz", cv::IMREAD_UNCHANGED);
cv::Mat test_images = cv::imread("t10k-images-idx3-ubyte.gz", cv::IMREAD_UNCHANGED);
cv::Mat test_labels = cv::imread("t10k-labels-idx1-ubyte.gz", cv::IMREAD_UNCHANGED);

std::cout << "Train images: " << train_images.size() << std::endl;


std::cout << "Train labels: " << train_labels.size() << std::endl;
std::cout << "Test images: " << test_images.size() << std::endl;
std::cout << "Test labels: " << test_labels.size() << std::endl;

return 0;


}
```

Затем мы можем визуализировать несколько случайных изображений из набора данных.


```cpp
#include


#include

int main() {


// Load MNIST dataset
cv::Mat train_images = cv::imread("train-images-idx3-ubyte.gz", cv::IMREAD_UNCHANGED);
cv::Mat train_labels = cv::imread("train-labels-idx1-ubyte.gz", cv::IMREAD_UNCHANGED);

// Visualize some random images


cv::RNG rng;
for (int i = 0; i < 10; i++) {
int index = rng.uniform(0, train_images.rows);
cv::Mat image = train_images.row(index).reshape(1, 28);
cv::imshow(std::to_string(i), image);
}

cv::waitKey(0);


cv::destroyAllWindows();

return 0;


}
```

Затем мы создадим нейронную сеть с несколькими скрытыми слоями и функцией активации ReLU.


```cpp
#include


#include

class NeuralNetwork {


public:
NeuralNetwork() {
// Initialize weights and biases
weights1 = cv::Mat::zeros(inputSize, hiddenSize, CV_32FC1);
cv::randn(weights1, 0, 0.01);
weights2 = cv::Mat::zeros(hiddenSize, outputSize, CV_32FC1);
cv::randn(weights2, 0, 0.01);
biases1 = cv::Mat::zeros(1, hiddenSize, CV_32FC1);
biases2 = cv::Mat::zeros(1, outputSize, CV_32FC1);
}

cv::Mat predict(cv::Mat x) {


// Forward propagation
cv::Mat a1 = x * weights1 + biases1;
cv::Mat h1 = relu(a1);
cv::Mat a2 = h1 * weights2 + biases2;
cv::Mat y = softmax(a2);

return y;


}

private:
const int inputSize = 784;


const int hiddenSize = 256;
const int outputSize = 10;
cv::Mat weights1;
cv::Mat biases1;
cv::Mat weights2;
cv::Mat biases2;

cv::Mat relu(cv::Mat x) {


return cv::max(x, cv::Mat::zeros(x.size(), x.type()));
}

cv::Mat softmax(cv::Mat x) {


cv::Mat exp_x;
cv::exp(x, exp_x);
return exp_x / cv::sum(exp_x)[0];
}
};

int main() {


// Load MNIST dataset
cv::Mat train_images = cv::imread("train-images-idx3-ubyte.gz", cv::IMREAD_UNCHANGED);
cv::Mat train_labels = cv::imread("train-labels-idx1-ubyte.gz", cv::IMREAD_UNCHANGED);
cv::Mat test_images = cv::imread("t10k-images-idx3-ubyte.gz", cv::IMREAD_UNCHANGED);
cv::Mat test_labels = cv::imread("t10k-labels-idx1-ubyte.gz", cv::IMREAD_UNCHANGED);

// Normalize images


train_images.convertTo(train_images, CV_32FC1, 1.0 / 255.0);
test_images.convertTo(test_images, CV_32FC1, 1.0 / 255.0);

// One-hot encode labels


cv::Mat train_labels_onehot = cv::Mat::zeros(train_labels.size(), CV_32FC10);
cv::Mat test_labels_onehot = cv::Mat::zeros(test_labels.size(), CV_32FC10);
for (int i = 0; i < train_labels.rows; i++) {
train_labels_onehot.at(i, train_labels.at(i)) = 1;
}
for (int i = 0; i < test_labels.rows; i++) {
test_labels_onehot.at(i, test_labels.at(i)) = 1;
}

// Train neural network


NeuralNetwork nn;
float learning_rate = 0.1;
int num_epochs = 10;
int batch_size = 64;
int num_batches = train_images.rows / batch_size;
for (int epoch = 0; epoch < num_epochs; epoch++) {
// Shuffle training data
cv::randShuffle(train_images, 1);
cv::randShuffle(train_labels_onehot, 1);
for (int batch = 0; batch < num_batches; batch++) {
// Get batch
int start_index = batch * batch_size;
int end_index = start_index + batch_size;
cv::Mat x_batch = train_images.rowRange(start_index, end_index);
cv::Mat y_batch = train_labels_onehot.rowRange(start_index, end_index);

// Forward propagation


cv::Mat y_pred = nn.predict(x_batch);

// Calculate loss


float loss = cross_entropy_loss(y_batch, y_pred);

// Backward propagation


cv::Mat delta2 = (y_pred - y_batch) / batch_size;
cv::Mat delta1 = delta2 * nn.weights2.t() * relu_derivative(nn.weights1 * x_batch.t() + nn.biases1);
cv::Mat dweights2 = (delta2.t() * nn.weights2.t()).t() / batch_size;
cv::Mat dbiases2 = cv::Mat::zeros(1, nn.biases2.cols, CV_32FC1);
cv::reduce(delta2, dbiases2, 0, cv::REDUCE_SUM);
cv::Mat dweights1 = (delta1.t() * x_batch).t() / batch_size;
cv::Mat dbiases1 = cv::Mat::zeros(1, nn.biases1.cols, CV_32FC1);
cv::reduce(delta1, dbiases1, 0, cv::REDUCE_SUM);

// Update weights and biases


nn.weights2 -= learning_rate * dweights2;
nn.biases2 -= learning_rate * dbiases2;
nn.weights1 -= learning_rate * dweights1;
nn.biases1 -= learning_rate * dbiases1;

// Print progress


if (batch % 100 == 0) {
std::cout << "Epoch " << epoch + 1 << " Batch " << batch + 1 << " Loss " << loss << std::endl;
}
}

// Test neural network


cv::Mat y_pred = nn.predict(test_images);
float accuracy = accuracy_score(test_labels_onehot, y_pred);
std::cout << "Epoch " << epoch + 1 << " Test Accuracy " << accuracy << std::endl;
}

return 0;


}

float cross_entropy_loss(cv::Mat y_true, cv::Mat y_pred) {


cv::Mat log_y_pred;
cv::log(y_pred, log_y_pred);
return -cv::sum(y_true.mul(log_y_pred))[0];
}

cv::Mat relu_derivative(cv::Mat x) {


return (x > cv::Mat::zeros(x.size(), x.type()));
}

float accuracy_score(cv::Mat y_true, cv::Mat y_pred) {


cv::Mat y_true_argmax, y_pred_argmax;
cv::reduce(y_true, y_true_argmax, 1, cv::REDUCE_ARGMAX);
cv::reduce(y_pred, y_pred_argmax, 1, cv::REDUCE_ARGMAX);
cv::Mat cmp = (y_true_argmax == y_pred_argmax);
return cv::countNonZero(cmp) / (float)cmp.rows;
}

В этом коде мы определяем класс нейронной сети NeuralNetwork с двумя скрытыми слоями, где функция активации представляет собой выпрямленную линейную единицу (ReLU), а выходной слой использует функцию softmax. Функция обучения обучает нейронную сеть, используя стохастический градиентный спуск и кросс-энтропийную потерю. Мы также определяем вспомогательные функции для вычисления потерь, производной функции ReLU и оценки точности.


В основной функции мы загружаем набор данных MNIST, нормализуем значения пикселей и конвертируем метки в векторы с горячим кодированием. Затем мы создаем объект NeuralNetwork и обучаем его с использованием обучающего набора данных. После каждой эпохи мы проверяем точность нейронной сети на тестовом наборе данных и распечатываем результаты.


Это всего лишь базовый пример, и есть много способов улучшить производительность нейронной сети, например, используя больше слоев, различные функции активации или методы регуляризации.




Download 49.55 Kb.

Do'stlaringiz bilan baham:
1   2   3   4   5




Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©fayllar.org 2024
ma'muriyatiga murojaat qiling