Собственная нейронная сеть. Просто как дважды два
Многие хотят написать свою нейросеть, но теряются в тоннах книг по машинному обучению, и сложных математических формулах. Сегодня я покажу вам относительно простой пример нейросети на Python, который работает просто и понятно.
Есть множество разных видов нейросетей, и целей для которых они служат. В общем случае схема работы нейросети такова:
- Создают программу используя библиотеки для построения нейросетей
- Обучают программу на БОЛЬШОМ наборе данных, то есть дают ей набор данных, правильно размеченный человеком, чтобы нейросеть обучилась и начала работать на других похожих наборах данных
- Сохраняют и используют обученную нейросеть
Я в своем примере совместил обучение нейросети вместе с ее тестированием, поэтому при каждом запуске нейросеть сперва обучается(что занимает некоторое время, не думайте что программа зависла). Если вы захотите использовать данный пример в своих проектах то разделите скрипт на две части - первая будет обучать модель и сохранять её, а вторая работать на основе уже сохраненной модели. Подробнее о сохранении и загрузке моделей можно почитать тут.
К тому же в моем примере я буду использовать очень маленький набор данных, в реальных проектах набор данных должен быть минимум из нескольких тысяч строк.
Итак, мы создадим нейросеть которая пытается угадать какой тип контента нужно найти для пользователя, в ответ на его вопрос. Например, если пользователь спросит "Кто такой Виктор Цой", нейросеть должна ответить "Информация о личности". Она не будет отвечать на вопрос, просто классифицирует вопрос в определенную категорию. Обучающий набор данных очень маленький поэтому тестировать будем на более-менее похожих вопросах.
Сперва создадим набор данных для обучения. У меня это обычный текстовый файл в котором лежат строки, разделенные значком @. Назовите файл 1.txt и положите его рядом со скриптом нейросети. Используйте кодировку UTF-8.
Образец файла (отрывок)
Что такое патока @ Информация о предмете
Где живут медведи @ Местоположение
Как зовут сына Трампа @ Имя
Как зовут Мадонну @ Имя
Как зовут Бьорк @ Имя
Почему небо голубое @ Информация о предмете
Как сварить борщ @ Инструкция
Как научиться летать @ Инструкция
Сколько звезд на небе @ Количество
Кто такая Мадонна @ Информация о личности
Какая высота у Эйфелевой башни @ Количество
Дата рождения Путина @ Дата рождения
Когда началась вторая Мировая война @ Дата события
Когда родился Майкл Джексон @ Дата рождения
Почему идет дождь @ Информация о предмете
В каких фильмах играл Ди Каприо @ Информация о предмете
Когда родился Эйнштейн @ Дата рождения
Какой город начинает упоминаться с 1147 года @ Дата
Что такое «дождь» @ Информация о предмете
Кто основал Санкт-Петербург @ Имя
Кто такой Христофор Колумб @ Информация о личности
Как звали Колумба @ Имя
Какой страной управляет королева Елизавета II @ Местоположение
Какова средняя глубина Тихого океана @ Количество
Какова высота Биг Бена @ Количество
В какой стране столицей является город Москва @ Местоположение
Полная версия файла для обучения нейросети
Установка модулей для Ubuntu
sudo apt install python3-pip
Скачиваем и распаковываем PyStemmer-1.3.0.tar.gz с сайта https://pypi.python.org/pypi/PyStemmer/1.3.0 в папку pystemmer.
cd pystemmer/
sudo python3 setup.py install
cd ..
pip3 install numpy
pip3 install sklearn
pip3 install scipy
Важно, запускается это чудо командой python3
Теперь покажу сам скрипт нейросети для классификации вопросов.
Код
Файл main.py - листинг кода
# -*- coding: utf-8 -*-
import sys
import numpy as np
import pickle
import re
from Stemmer import Stemmer
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model import SGDClassifier
from sklearn.pipeline import Pipeline
from sklearn.metrics import accuracy_score
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# очистка текста с помощью regexp приведение слов в инфинитив и нижний регистр, замена цифр
def text_cleaner(text):
text = text.lower() # приведение в lowercase
stemmer = Stemmer('russian')
text = ' '.join( stemmer.stemWords( text.split() ) )
text = re.sub( r'\b\d+\b', ' digit ', text ) # замена цифр
return text
# - - - - - - - - - - - - - - - - - - - - - - - - -
# загрузка данных из файла 1.txt
#
def load_data():
data = { 'text':[],'tag':[] }
for line in open('1.txt'):
if(not('#' in line)):
row = line.split("@")
data['text'] += [row[0]]
data['tag'] += [row[1]]
return data
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Обучение нейросети
def train_test_split( data, validation_split = 0.1):
sz = len(data['text'])
indices = np.arange(sz)
np.random.shuffle(indices)
X = [ data['text'][i] for i in indices ]
Y = [ data['tag'][i] for i in indices ]
nb_validation_samples = int( validation_split * sz )
return {
'train': { 'x': X[:-nb_validation_samples], 'y': Y[:-nb_validation_samples] },
'test': { 'x': X[-nb_validation_samples:], 'y': Y[-nb_validation_samples:] }
}
# - - - - - - - - - - - - - - - - - - - -
def openai():
data = load_data()
D = train_test_split( data )
text_clf = Pipeline([
('tfidf', TfidfVectorizer()),
('clf', SGDClassifier(loss='hinge')),
])
text_clf.fit(D['train']['x'], D['train']['y'])
predicted = text_clf.predict( D['train']['x'] )
# Начало тестирования программы
z=input("Введите вопрос без знака вопроса на конце: ")
zz=[]
zz.append(z)
predicted = text_clf.predict( zz )
print(predicted[0])
# - - - - - - - - - - - - - - - - - - - -
if __name__ == '__main__':
sys.exit( openai() )
Давайте запустим нашу нейросеть, подождем пока она обучится и предложит нам ввести вопрос. Введем вопрос которого нет в обучающем файле - "Кто придумал ракету". Писать нужно без знака вопроса на конце. В ответ нейросеть выдаст "Имя", значит она определила что наш вопрос подразумевает ответ в котором должно быть чье-то имя. Заметьте, данного вопроса не было в файле 1.txt но нейросеть безошибочно определила что мы имеем ввиду, исходя из обучающей выборки.
Данный классификатор очень прост. Вы можете подать на вход в файл 1.txt абсолютно любые данные которые нужно классифицировать, это не обязательно должны быть вопросы и их категории как в моем примере.
Демонстрация работы скрипта
Материал об этой очень интересной разработке подготовил @pythono
Скрипт мною лично запущен и протестирован, что вы можете видеть на видео выше:)
Что с этим можно сделать
Есть идея обучить сеть на комментариях Голоса. Скажите, вам было бы это интересно? Готовы ли вы помочь классифицировать комментарии по категориям спам/флуд/вопрос/шутка/мат ?