Skip to content

Gando4lapi/Multilayer-Perceptron-MNIST

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 

Repository files navigation

Determining-the-handmade-number-using-PyTorch

Проект для распознавания рукописных цифр (от 0 до 9) с использованием библиотеки PyTorch и датасета MNIST.

📋 Содержание

🎯 О проекте

Цель проекта — научить компьютер распознавать рукописные цифры с помощью нейронной сети. Используем датасет MNIST — популярный набор из 70,000 изображений цифр размером 28x28 пикселей.

Что делает проект:

  • Загружает датасет MNIST
  • Обучает простую нейронную сеть
  • Тестирует модель на новых данных
  • Показывает точность распознавания
  • Визуализирует примеры цифр

🛠 Технологии

  • Python 3.x
  • PyTorch - библиотека для создания нейронных сетей
  • TorchVision - загрузка и обработка изображений
  • NumPy - работа с массивами и числами
  • Matplotlib - создание графиков и визуализаций
  • tqdm - красивый индикатор прогресса

📦 Установка

  1. Клонируйте репозиторий:
git clone https://github.com/Gando4lapi/-Multilayer-Perceptron-Determining-the-handmade-number-using-PyTorch
cd -Multilayer-Perceptron-Determining-the-handmade-number-using-PyTorch
  1. Установите зависимости:
pip install torch torchvision numpy matplotlib tqdm

📖 Объяснение кода

В представленном коде создаётся многослойный персептрон для MNIST: импортируются библиотеки, определяется класс модели с тремя полносвязными слоями и ReLU между ними, загружается датасет, настраиваются загрузчики, функция потерь и оптимизатор.

Импорты

import torch — подключает ядро PyTorch: тензоры, автодифференцирование, устройство CPU/GPU.

import torch.nn as nn — модуль нейронных сетей с готовыми слоями и базовым классом nn.Module.

import torch.nn.functional as F — функциональные версии операций (ReLU, Conv2d и т.д.); в текущем фрагменте не используется, но часто вызывают F.relu.

from torchvision import datasets, transforms — наборы данных и преобразования изображений; отсюда берётся MNIST и превращение в тензоры.

import numpy as np — библиотека численных массивов; прямо в этом коде не используется.

import matplotlib.pyplot as plt — построение графиков; прямо в этом коде не используется.

from tqdm.notebook import tqdm — прогресс‑бар, удобный в Jupyter для визуализации итераций обучения/теста.

Определение модели

class MNIST_Multilayer_Perceptron(nn.Module): — объявляет класс модели как наследника nn.Module, чтобы PyTorch мог зарегистрировать слои и их параметры.

def init(self): — конструктор класса; здесь создаются и регистрируются слои модели. Важно именно двойное подчёркивание с обеих сторон.

super().init() — инициализация базового nn.Module; регистрирует внутренние структуры для параметров и подмодулей.

self.net = nn.Sequential( ... ) — контейнер, который последовательно применяет слои:

nn.Linear(784, 256) — полносвязный слой, принимает развёрнутое изображение 28×28=784 признаков и выводит 256 признаков.

nn.ReLU() — нелинейная активация поэлементно, добавляет выразительность.

nn.Linear(256, 128) — второй полносвязный слой: 256 → 128.

nn.ReLU() — вторая нелинейность.

nn.Linear(128, 10) — выходной слой: 10 логитов (по одному на класс цифры 0–9).

def forward(self, x): — метод прямого прохода; определяет вычисление выхода по входу.

return self.net(x) — прогоняет вход через последовательность слоёв и возвращает логиты без softmax (он встроен внутрь CrossEntropyLoss).

Важно: ранее у вас были ошибки из‑за опечаток init вместо init, super.init вместо super().init и из‑за того, что forward был с неправильным отступом внутри конструктора. Это приводило к пустому списку параметров у модели и ошибке оптимизатора. В рабочем варианте имя конструктора и super должны быть с двойными подчёркиваниями, а forward — на том же уровне отступа, что и init.

Загрузка данных

mnist_train = datasets.MNIST(root="./datasets", train=True, transform=transforms.ToTensor(), download=True) — загружает тренировочную часть MNIST в папку ./datasets; ToTensor преобразует PIL‑изображение 28×28 в тензор формы с нормированием значений в.

mnist_test = datasets.MNIST(root="./datasets", train=False, transform=transforms.ToTensor(), download=True) — загружает тестовую часть аналогично.

train_loader = torch.utils.data.DataLoader(mnist_train, batch_size=100, shuffle=True) — итератор по мини‑батчам тренировочных данных: по 100 изображений, с перемешиванием батчей перед каждой эпохой.

test_loader = torch.utils.data.DataLoader(mnist_test, batch_size=100, shuffle=False) — итератор по тестовым данным: по 100 изображений, без перемешивания.

Практический совет: к ToTensor() обычно добавляют Normalize((0.1307,), (0.3081,)) для стандартизации MNIST, что помогает обучению.

Создание объектов обучения

model = MNIST_Multilayer_Perceptron() — создаёт экземпляр МLP с тремя линейными слоями и двумя ReLU.

criterion = nn.CrossEntropyLoss() — функция потерь для многоклассовой классификации; ожидает сырые логиты размера [batch, 10] и целочисленные метки классов [batch].

optimizer = torch.optim.SGD(model.parameters(), lr=0.1) — оптимизатор стохастического градиентного спуска; получает список параметров модели (веса и смещения слоёв) и шаг обучения 0.1. При желании можно добавить momentum=0.9 или заменить на Adam(lr=1e-3).

Если при создании оптимизатора появляется ValueError: optimizer got an empty parameter list, почти всегда проблема в том, что слои не зарегистрированы (например, из‑за init вместо init) или optimizer создаётся до инициализации модели. После исправления конструктора и порядка строк ошибка исчезнет.

Дальнейшие шаги (обучающий цикл)

Перед обучением включают режим обучения: model.train().

В цикле по train_loader на каждом батче:

optimizer.zero_grad() — обнуляет накопленные градиенты.

x = images.view(-1, 28*28) — разворачивает батч из формы [B, 1, 28, 28] в [B, 784] для подачи в линейный слой.

y = model(x) — прямой проход, получаем логиты [B, 10].

loss = criterion(y, labels) — вычисление кросс‑энтропии.

loss.backward() — обратное распространение градиентов.

optimizer.step() — обновление параметров.

Оценка на тесте

model.eval() — включает режим оценки (важно при наличии Dropout/BatchNorm).

with torch.no_grad(): — отключает вычисление градиентов для экономии ресурсов.

Прогон по test_loader: разворот входа, прямой проход, preds = torch.argmax(y, dim=1), сравнение с labels и подсчёт доли верных предсказаний.

Технические детали:

  • Тип: Многослойный персептрон (нелинейный классификатор)
  • Входной размер: 784 (28×28 пикселей)
  • Выходной размер: 10 (классы 0-9)
  • Функция потерь: CrossEntropyLoss
  • Оптимизатор: SGD с learning rate = 0.1

📊 Результаты

  • Точность на тестовых данных: ~91%

👤 Автор

Капник Данил


⭐ Поставьте звездочку, если проект был полезен!

About

In this repository, I trained using the Duke University method and tested the MNIST dataset of handmade numbers using PyTorch

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors