Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Lab4 / ИССЛабораторная №4

.docx
Скачиваний:
0
Добавлен:
10.05.2024
Размер:
1.14 Mб
Скачать

Лабораторная работа №4

Введение в нейронные сети в Python. Градиентный спуск

Цель работы: экспериментальное изучение построение нейронных сети в Python.

Ход работы

  1. Изменили функцию по варианту:

def target_function(x):

    return torch.tan(x)

Количество эпох 100, количество скрытых нейронов 5.

Количество эпох 1000, количество скрытых нейронов 10.

Количество эпох 2000, количество скрытых нейронов 100.

  1. Изменить архитектуру сети следующим образом:

  1. Количество полносвязных слоев 3;

Изменили кол-во слоев RegressionNet на 3, удалив один слой из описания класса RegressionNet:

class RegressionNet(torch.nn.Module):

def __init__(self, n_hidden_neurons):

super().__init__()

self.fc1 = torch.nn.Linear(1, n_hidden_neurons)

self.act1 = torch.nn.Tanh()

self.fc2 = torch.nn.Linear(n_hidden_neurons, n_hidden_neurons)

self.act2 = torch.nn.Tanh()

# self.fc3 = torch.nn.Linear(n_hidden_neurons, 1)

def forward(self, x):

x = self.fc1(x)

x = self.act1(x)

x = self.fc2(x)

x = self.act2(x)

# x = self.fc3(x)

return x

Количество эпох 100, количество скрытых нейронов 5.

Количество эпох 1000, количество скрытых нейронов 10.

Количество эпох 2000, количество скрытых нейронов 100.

  1. Количество полносвязных слоев 4;

Добавили еще один слой в класс RegressionNet:

class RegressionNet(torch.nn.Module):

def __init__(self, n_hidden_neurons):

super().__init__()

self.fc1 = torch.nn.Linear(1, n_hidden_neurons)

self.act1 = torch.nn.Tanh()

self.fc2 = torch.nn.Linear(n_hidden_neurons, n_hidden_neurons)

self.act2 = torch.nn.Tanh()

self.fc3 = torch.nn.Linear(n_hidden_neurons, n_hidden_neurons)

self.act3 = torch.nn.Tanh()

self.fc4 = torch.nn.Linear(n_hidden_neurons, 1) # Новый, четвертый слой

def forward(self, x):

x = self.fc1(x)

x = self.act1(x)

x = self.fc2(x)

x = self.act2(x)

x = self.fc3(x)

x = self.act3(x)

x = self.fc4(x) # Пропуск через четвертый слой

return x

Количество эпох 100, количество скрытых нейронов 5.

Количество эпох 1000, количество скрытых нейронов 10.

Количество эпох 2000, количество скрытых нейронов 100.

  1. Функции активации заменить на сигмоидные, тангенсальные, ReLU.

Изменили функции активации в местах в классе RegressionNet. Для сигмоидной, тангенсальной и ReLU:

class RegressionNet(torch.nn.Module):

def __init__(self, n_hidden_neurons):

super().__init__()

self.fc1 = torch.nn.Linear(1, n_hidden_neurons)

self.act1 = torch.nn.Sigmoid() # Сигмоидная функция активации

self.fc2 = torch.nn.Linear(n_hidden_neurons, n_hidden_neurons)

self.act2 = torch.nn.Tanh() # Тангенсальная функция активации

self.fc3 = torch.nn.Linear(n_hidden_neurons, n_hidden_neurons)

self.act3 = torch.nn.ReLU() # Функция активации ReLU

self.fc4 = torch.nn.Linear(n_hidden_neurons, 1) # Слой для выхода

def forward(self, x):

x = self.fc1(x)

x = self.act1(x)

x = self.fc2(x)

x = self.act2(x)

x = self.fc3(x)

x = self.act3(x)

x = self.fc4(x)

return x

Количество эпох 100, количество скрытых нейронов 5.

Количество эпох 1000, количество скрытых нейронов 10.

Количество эпох 2000, количество скрытых нейронов 100.

Для каждой из архитектур (включая основную, которую получили в первом задании) изменили следующие параметры сети: количество эпох ( 100, 1000, 2000), количество скрытых нейронов (5, 10, 100).

  1. Заменили функцию потерь на следующую:

MSE:

def loss(pred, target):

return torch.nn.functional.smooth_l1_loss(pred, target)

Smooth L1 Loss:

# Функция потерь MSE

def loss_MSE(pred, target):

return torch.mean((pred - target) ** 2)

  1. Изменение шума в основной программе:

Изменили значение переменной noise, которая генерирует шум и добавляет его к y_train.

Увеличили уровень шума у до /10:

noise = torch.randn(y_train.shape) / 10

y_train = y_train + noise

Изменили диапазон значений x для обучающей выборки и значений x для валидационной модели, чтобы увидеть разницу изменения шума в программе.

x_train = torch.linspace(-5, 2, 10)

x_validation = torch.linspace (-5, 2, 10)

Уменьшили уровень шума в 50 раз

noise = torch.randn(y_train.shape) / 50

y_train = y_train + noise

Уровень шума влияет на процесс обучения и качество модели. Уменьшение шума улучшает производительность модели, в то время как увеличение шума может привести к худшей производительности модели из-за усложнения выявления реальных закономерностей в данных.

Листинг программы:

import torch

import matplotlib.pyplot as plt

import random

import numpy as np

# Установка seed для воспроизводимости результатов

random.seed(0)

np.random.seed(0)

torch.manual_seed(0)

torch.cuda.manual_seed(0)

# Определение исходной функции

def target_function(x):

    return torch.tan(x)

# Определение функции потерь

def loss(pred, target):

    squares = abs((pred - target))  # Расчет функции потерь

    return squares.mean()

# Определение класса для нейронной сети

class RegressionNet(torch.nn.Module):

    def __init__(self, n_hidden_neurons):

        super().__init__()

        self.fc1 = torch.nn.Linear(1, n_hidden_neurons)

        self.act1 = torch.nn.Tanh()

        self.fc2 = torch.nn.Linear(n_hidden_neurons, n_hidden_neurons)

        self.act2 = torch.nn.Tanh()

        self.fc3 = torch.nn.Linear(n_hidden_neurons, 1)

    def forward(self, x):

        x = self.fc1(x)

        x = self.act1(x)

        x = self.fc2(x)

        x = self.act2(x)

        x = self.fc3(x)

        return x

# Функция предсказания с визуализацией исходной и предсказанной функций

def predict(net, x, y):

    y_pred = net.forward(x)  # Изменение параметров сети

    plt.plot(x.numpy(), y.numpy(), 'o', label='Groud truth')

    plt.plot(x.numpy(), y_pred.data.numpy(), 'o', c='r', label='Prediction');

    plt.legend(loc='upper left')  # Показать легенду

    plt.xlabel('$x$')  # Ось x

    plt.ylabel('$y$')  # Ось y

    plt.show()  # Показать график

# Подготовка данных для обучения и визуализации

x_train = torch.linspace(-10, 5, 100)

y_train = target_function(x_train)

noise = torch.randn(y_train.shape) / 20.  # Создание шума

plt.plot(x_train,y_train, label='Исходная функция')

y_train = y_train + noise

plt.plot(x_train,y_train, label='Зашумленная функция')

plt.legend()

plt.show()

x_train.unsqueeze_(1)

y_train.unsqueeze_(1)

x_validation = torch.linspace(-10, 5, 100)

y_validation = target_function(x_validation)

x_validation.unsqueeze_(1)

y_validation.unsqueeze_(1)

# Инициализация модели

net = RegressionNet(10)

predict(net, x_validation, y_validation)

optimizer = torch.optim.Adam(net.parameters(), lr=0.01)

epoch_num = 2000  # Количество эпох для обучения

loss_history = [[0, 0] for _ in range(epoch_num)]  # Хранение данных функции потерь

# Обучение нейронной сети

for epoch_index in range(epoch_num):

    optimizer.zero_grad()

    y_pred = net.forward(x_train)

    loss_val = loss(y_pred, y_train)

    # Сохранение данных о функции потерь

    loss_history[epoch_index][0] = epoch_index

    loss_history[epoch_index][1] = loss_val.data.numpy().tolist()

    loss_val.backward()  # Вычисление градиентов

    optimizer.step()  # Шаг оптимизации

# Визуализация результатов

predict(net, x_validation, y_validation)

plt.plot([row[0] for row in loss_history][100:], [row[1] for row in loss_history][100:], '.')

plt.title(label='Loss function')

plt.xlabel('Epoch_index')

plt.ylabel('Error')

plt.show()

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

Соседние файлы в папке Lab4