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

    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 высылается электронная книга.
    Издательский дом «Питер»
    Компания

    Комментарии 0

    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

    Самое читаемое