Изучение модели вычислений операция-операнд”
Проблемы, которые необходимо решить на нейрокомпьютерах
Download 49.55 Kb.
|
Кампютер архитектураси практика 2
Проблемы, которые необходимо решить на нейрокомпьютерах.
Одной из главных проблем, которую можно решить с помощью нейрокомпьютеров, является задача распознавания образов. В этой практической работе мы рассмотрим пример использования нейронной сети для распознавания рукописных цифр. Для начала, мы должны загрузить набор данных MNIST, который содержит 60 000 изображений рукописных цифр для обучения и 10 000 изображений для тестирования. Мы будем использовать библиотеку `OpenCV` для загрузки изображений. ```cpp
#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 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 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 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 } for (int i = 0; i < test_labels.rows; i++) { test_labels_onehot.at } 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); 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; } } 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: |
ma'muriyatiga murojaat qiling