python

Книга «Глубокое обучение с подкреплением на Python. OpenAI Gym и TensorFlow для профи»

  • среда, 18 сентября 2019 г. в 00:26:55
https://habr.com/ru/company/piter/blog/465605/
  • Блог компании Издательский дом «Питер»
  • Python
  • Профессиональная литература


image Привет, Хаброжители! Глубокое обучение с подкреплением (Reinforcement Learning) — самое популярное и перспективное направление искусственного интеллекта. Практическое изучение RL на Python поможет освоить не только базовые, но и передовые алгоритмы глубокого обучения с подкреплением. Эта книга предназначена для разработчиков МО и энтузиастов глубокого обучения, интересующихся искусственным интеллектом и желающих освоить метод обучения с подкреплением. Прочитайте эту книгу и станьте экспертом в области обучения с подкреплением, реализуя практические примеры в работе или вне ее. Знания в области линейной алгебры, математического анализа и языка программирования Python помогут вам понять логику изложения материала.

Отрывок. Генерирование текстов песен посредством LSTM RNN


А теперь посмотрим, как использовать LSTM для генерирования текстов песен Зейна Малика. Набор данных с текстами песен Зейна можно загрузить по адресу https://github.com/sudharsan13296/Hands-On-Reinforcement-Learning-With-Python/blob/master/07.%20Deep%20Learning%20Fundamentals/data/ZaynLyrics.txt.

Работа начинается с импортирования необходимых библиотек:

import tensorflow as tf
import numpy as np

Затем читается файл с текстами песен:

with open("Zayn_Lyrics.txt","r") as f: 
    data=f.read() 
    data=data.replace('\n','') 
    data = data.lower()

Убедимся в том, что данные были успешно загружены:

data[:50]
"now i'm on the edge can't find my way it's inside "

Теперь все символы сохраняются в переменной all_chars:

all_chars=list(set(data))

Количество уникальных символов сохраняется в unique_chars:

unique_chars = len(all_chars)

А общее количество символов сохраняется в переменной total_chars:

total_chars =len(data)

Сначала мы присвоим каждому символу индекс. char_to_ix будет содержать отображение символа на индекс, а ix_to_char — отображение индекса на символ:

char_to_ix = { ch:i for i,ch in enumerate(all_chars) }
ix_to_char = { i:ch for i,ch in enumerate(all_chars) }

Пример:

char_to_ix['e']
9

ix_to_char[9]
e

Затем определяется функция generate_batch, которая генерирует входные и целевые значения. Целевые значения равны сдвигу входного значения, умноженному на i.

Например, если input = [12,13,24] со значением сдвига 1, то целевые значения будут равны [13,24]:

def generate_batch(seq_length,i):
    inputs = [char_to_ix[ch] for ch in data[i:i+seq_length]]
    targets = [char_to_ix[ch] for ch in data[i+1:i+seq_length+1]]
    inputs=np.array(inputs).reshape(seq_length,1)
    targets=np.array(targets).reshape(seq_length,1)
    return inputs,targets

Мы определим длину последовательности, скорость обучения и количество узлов, которое равно числу нейронов:

seq_length = 25
learning_rate = 0.1
num_nodes = 300

Построим LSTM RNN. TensorFlow предоставляет функцию BasicLSTMCell() для построения ячеек LSTM; вы должны задать количество единиц в ячейке LSTM и тип используемой функции активации.

Итак, мы создаем ячейку LSTM и строим сеть RNN с этой ячейкой при помощи функции tf.nn.dynamic_rnn(), которая возвращает выход и значение состояния:

def build_rnn(x):
        cell= tf.contrib.rnn.BasicLSTMCell(num_units=num_nodes,
activation=tf.nn.relu)
        outputs, states = tf.nn.dynamic_rnn(cell, x, dtype=tf.float32)
        return outputs,states

Теперь создадим заместителя для входа X и цели Y:

X=tf.placeholder(tf.float32,[None,1])
Y=tf.placeholder(tf.float32,[None,1])

Преобразуем X и Y в int:

X=tf.cast(X,tf.int32)
Y=tf.cast(Y,tf.int32)

Также создадим onehot-представления для X и Y:

X_onehot=tf.one_hot(X,unique_chars)
Y_onehot=tf.one_hot(Y,unique_chars)

Получим выходы и состояния от RNN вызовом функции build_rnn:

outputs,states=build_rnn(X_onehot)

Транспонируем выход:

outputs=tf.transpose(outputs,perm=[1,0,2])

Инициализируем веса и смещение:

W=tf.Variable(tf.random_normal((num_nodes,unique_chars),stddev=0.001))
B=tf.Variable(tf.zeros((1,unique_chars)))

Вычислим выход, умножая выход на веса и прибавляя смещение:

Ys=tf.matmul(outputs[0],W)+B

Теперь выполним softmax-активацию и получим вероятности:

prediction = tf.nn.softmax(Ys)

Потеря cross_entropy будет вычислена в следующем виде:

cross_entropy=tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels
=Y_onehot,logits=Ys))

Наша цель — минимизация потери, поэтому мы выполним обратное распространение для сети и проведем градиентный спуск:

optimiser =
tf.train.GradientDescentOptimizer(learning_rate=learning_rate).minimize(cro
ss_entropy)

Затем будет определена вспомогательная функция predict, которая даст индексы следующего прогнозируемого символа в соответствии с моделью RNN:

def predict(seed,i):
    x=np.zeros((1,1))
    x[0][0]= seed
    indices=[]
    for t in range(i):
        p=sess.run(prediction,{X:x})
        index = np.random.choice(range(unique_chars), p=p.ravel())
        x[0][0]=index
        indices.append(index)
    return indices

Затем будет задан размер пакета batch_size, количество пакетов и количество эпох, а также величина сдвига shift для генерирования пакета:

batch_size=100
total_batch=int(total_chars//batch_size)
epochs=1000
shift=0

Наконец, мы создаем сеанс TensorFlow и строим модель:

init=tf.global_variables_initializer()

with tf.Session() as sess:
    sess.run(init)
    for epoch in range(epoch):
        print("Epoch {}:".format(epoch))
        if shift + batch_size+1 >= len(data):
            shift =0
        # Получить ввод и цель для каждого пакета функцией
        # generate_batch, которая сдвигает ввод на величину shift,
        # и сформировать цель
        for i in range(total_batch):
            inputs,targets=generate_batch(batch_size,shift)
            shift += batch_size
            # calculate loss
            if(i%100==0):
                loss=sess.run(cross_entropy,feed_dict={X:inputs,
Y:targets})
                # Получаем индекс следующего спрогнозированного символа
                # при помощи функции predict
index =predict(inputs[0],200)
                # передаем индекс в словарь ix_to_char
                # и получаем символ
                txt = ''.join(ix_to_char[ix] for ix in index)
                print('Iteration %i: '%(i))
                print ('\n %s \n' % (txt, ))
            sess.run(optimiser,feed_dict={X:inputs,Y:targets})

Как видно из результатов, в исходной эпохе выход состоит из случайных символов, но по мере обучения результаты улучшаются:

Epoch 0:
Iteration 0:

 wsadrpud,kpswkypeqawnlfyweudkgt,khdi nmgof' u vnvlmbis .
snsblp,podwjqehb,e;g-
'fyqjsyeg,byjgyotsrdf;;u,h.a;ik'sfc;dvtauofd.,q.;npsw'wjy-quw'quspfqw-
.
.
.
Epoch 113:
Iteration 0:
i wanna see you, yes, and she said yes!

Об авторе


Судхарсан Равичандиран — специалист по обработке и анализу данных, горячий поклонник искусственного интеллекта и видеоблогер. Он получил степень бакалавра в области computer science в Университете Анны и занимается исследованиями практической реализации глубокого обучения и обучения с подкреплением, включая обработку естественных языков и компьютерное зрение. Ранее работал внештатным веб-дизайнером и разработчиком, участвовал в создании ряда сайтов, отмеченных наградами. В настоящее время принимает участие в проектах с открытым кодом и часто отвечает на вопросы на Stack Overflow.

О научных редакторах


Суджит Пал (Sujit Pal) — руководитель технических исследований в Elsevier Labs, группы разработки новейших технологий компании Reed-Elsevier Group. Занимается исследованиями в области семантического поиска, обработки естественных языков, машинного и глубокого обучения. В Elsevier работал над несколькими инициативными проектами, включая оценку и совершенствование качества поиска, классификацию изображений и выявление дубликатов, аннотацию и разработку антологий медицинских и научных текстов. Он написал книгу о глубоком обучении совместно с Антонио Галли (Antonio Gulli) и пишет о технологиях в своем блоге Salmon Run.

Сурьядипан Рамамурти (Suriyadeepan Ramamoorthy) — исследователь искусственного интеллекта и инженер из AI researcher and engineer в Пондичерри (Индия). Основная тематика его работ — понимание естественных языков и формирование рассуждений. Он активно пишет в блоге, посвященном глубокому обучению. В SAAMA Technologies он применяет расширенные методы глубокого обучения для анализа биомедицинских текстов. Являясь ярым сторонником свободно распространяемого ПО, активно участвует в проектах по его разработке в сообществе FSFTN. Также интересуется коллективными сетями, визуализацией данных и творческим программированием.

» Более подробно с книгой можно ознакомиться на сайте издательства
» Оглавление
» Отрывок

Для Хаброжителей скидка 25% по купону — Python

По факту оплаты бумажной версии книги на e-mail высылается электронная книга.