Полностью соединенная нейронная сеть¶
Полностью соединенная нейронная сеть используется как для задач регрессии, так и классификации, но не ограничивается в этом. Вы можете найти линейные(полностью соединенные) слои практически в каждом типe сети. В PyTorch линейный слой представляется классом torch.nn.Linear
. Обычно нейронная сеть заканчивается torch.nn.Linear
с функцией активации в последнем слое, отражающая то, что вам нужно на выходе. Вам нужны вероятности, то есть данные от 0 до 1, вы используете функцию активации Sigmoid, представленная torch.nn.functional.sigmoid
. Если вы делаете мультиклассовую классификацию, то вы можете использовать torch.nn.Softmax
или torch.nn.LogSoftmax
. Обычно после каждого линейного слоя есть функция активация torch.nn.functional.relu
. Вам нужные данные на выходе от -1 до 1, то используйте torch.nn.functional.tanh
.
Этот ноутбук и датасеты доступны в моем Github репозитории:
git clone https://github.com/andreiliphd/reinforcement-content.git
Если нет Git, то его нужно установить.
Linux:
sudo apt-get update
sudo apt-get install git
Windows: скачайте Git с сайта git-scm.com.
Если вы нашли ошибку на сайте, ее можно исправить самостоятельно сделав Pull Request в Git.
Видео¶
Видео, описывающее полностью соединенную нейронную сеть.
from IPython.display import IFrame
IFrame('https://www.youtube.com/embed/YXdR7ryazmE', width="560", height="315")
Этапы решения задачи¶
- Загрузка и аугментация данных.
- Декларирование модели.
- Инстанциирование модели.
- Инстанциирование функции потерь(лосс).
- Инстанциирование оптимизатора.
- Создание тренировочной петли(лупа).
Загрузка и аугментация данных¶
Сначала импортируем необходимые библиотеки.
import numpy as np
import pandas as pd
from sklearn.preprocessing import MinMaxScaler
from sklearn.model_selection import train_test_split
import torch
Загружаем данные в pandas
. pandas
- это Excel для Python.
data = pd.read_csv('datasets/csv/equities.csv')
Нейронные сети не могут работать с отсутствующими или другими словами NA
данными. Есть несколько механизмов по очистке данных от NA
и один из них - это заполнить отсутствующие данные нулями, что мы и сделаем.
data = data.fillna(0)
Удалим столбцы, которые нам не нужны в входных данных. Нам не нужные index
(индекс) и name
(название компании).
data_np = np.array(data.drop(['index', 'name'], axis = 1))
Нейронные сети работают хорошо с данными от 0 до 1 или от -1 до 1. Нормализуем данные, чтобы они отвечали данным критериям. Если вы не будете нормализовать данные то не получите хорошего результата, так как числовая стабильность будет очень маленькая.
scaler = MinMaxScaler()
data_scaled = scaler.fit_transform(data_np)
Выделим входные данные и метки. x
- это входные данные, то есть столбцы с финансовыми показателями. y
- это метки, то есть столбцы с капитализацией.
y = data_scaled[:, 28]
x = data_scaled[:, :28]
Разобьем датасет на тренировочный и тестовый. Это делается с целью дальнейшей проверки результатов прогноза.
X_train, X_test, y_train, y_test = train_test_split(x, y, test_size=0.25, random_state=42, shuffle=False)
Конвертируем данные в torch.tensor
.
X_train_torch = torch.from_numpy(X_train).float()
X_test_torch = torch.from_numpy(X_test).float()
y_train_torch = torch.from_numpy(y_train).float()
y_test_torch = torch.from_numpy(y_test).float()
Инстанциирование модели¶
torch.nn.Sequential
- это стиль Keras создания модели. PyTorch поддерживает такую декларацию модели. Мы просто делаем линейные слои torch.nn.Linear
(wx+b
) и torch.nn.ReLu
.
model = torch.nn.Sequential(
torch.nn.Linear(28, 100),
torch.nn.ReLU(),
torch.nn.Linear(100, 200),
torch.nn.ReLU(),
torch.nn.Linear(200,100),
torch.nn.ReLU(),
torch.nn.Linear(100, 50),
torch.nn.ReLU(),
torch.nn.Linear(50, 1)
)
Если есть видеокарта, то переносим данные на видеокарту для ускорения работы.
if torch.cuda.is_available():
model = model.cuda()
X_train_torch, y_train_torch = X_train_torch.cuda(), y_train_torch.cuda()
Инстанциирование функции потерь(лосс)¶
Обратите внимание мы используем torch.nn.MSELoss
, который как раз пригоден для задач регрессии.
criterion = torch.nn.MSELoss(reduction='sum')
Инстанциирование оптимизатора¶
torch.optim.Adam
- универсальный оптимизатор, который подходит как для задач регрессии, так и для задач классификации.
optimizer = torch.optim.Adam(model.parameters(), lr=1e-4)
Создание тренировочной петли(лупа)¶
for epoch in range(10):
output = model(X_train_torch)
loss = criterion(output, torch.reshape(y_train_torch, (15,1)))
print('Epoch: ', epoch, 'Loss: ', loss.item())
optimizer.zero_grad()
loss.backward()
optimizer.step()
Epoch: 0 Loss: 2.275873899459839 Epoch: 1 Loss: 2.2586419582366943 Epoch: 2 Loss: 2.242652177810669 Epoch: 3 Loss: 2.227229118347168 Epoch: 4 Loss: 2.2123847007751465 Epoch: 5 Loss: 2.1979880332946777 Epoch: 6 Loss: 2.1836135387420654 Epoch: 7 Loss: 2.1692001819610596 Epoch: 8 Loss: 2.1550140380859375 Epoch: 9 Loss: 2.1411094665527344
Обучение¶
Итак, после каждого линейного слоя нужна функцию активации для того, чтобы разрушить линейность, но не ставьте torch.nn.functional.relu
в конце нейронной сети, потому что она не будет обучаться. torch.nn.functional.relu
должен находиться между слоями. Когда вы ставите в конце нейронной сети функцию активации обратите внимание на инструкцию к функции потерь. Функция потерь может требовать особой функции активации. Если в инструкции не упомянута функция активации на выходе, то ставьте функции активации, которая решает вашу задачу или не ставьте ее вообще. Нейронная сеть работать будет без функции активации в конце и в некоторых случаях будет работать быстрее и лучше.
Записывайтесь на мой курс, где я расскажу все более детально и подробно, а главное простыми словами. Для меня нет глупых вопросов, для меня нет начинающих, для меня есть желающие познать и я помогаю им в этом.