Тематический план

  • Раздел 1. Введение в нейронные сети

    Машинное обучение. Виды признаков. Обучающая выборка. Задачи классификации, регрессии, ранжирования. Эмпирический риск. Обучение и переобучение.

    Задачи классификации и регрессии. Понятие отступа. Метод стохастического градиента. Математическая модель искусственного нейрона. Функция активации. Проблема полноты. Задача исключающего ИЛИ. Метод обратного распространения ошибки. Многослойная нейронная сеть. Эвристики обучения нейронной сети и ускорения сходимости. Формирование начального приближения. Проблема «паралича» сети. Метод послойной настройки сети. Подбор структуры сети. Метод постепенного усложнения сети. Промежуточные представления.

    Модель Word2vec. Модели CBoW и Skip-gram. Negative Sampling. Реализация модели word2vec в пакете Gensim.


    Практическое задание №1.

     

    1.     Запустите jupyter notebook, создайте тетрадку в папке с данными, импортируйте следующие модули

    import sys, json, codecs, csv

    import numpy as np

    import random

    import pandas as pd

    import tqdm

    import itertools

    import seaborn as sns

    # visualization

    import matplotlib

    import numpy as np

    import matplotlib.pyplot as plt

    %matplotlib inline

    Импортируйте модули nltk для препроцессинга текста

    from nltk.tokenize import word_tokenize, sent_tokenize

    from nltk.corpus import stopwords

    Импортируйте модули keras для создания нейронной сети

    from keras.layers import Dense, Activation

    from keras.layers import LSTM, GRU, Dropout, BatchNormalization

    from keras.layers import Input, Dense

    from keras.models import Model

    from keras.optimizers import RMSprop, Adam

     

    # word2vec

    from gensim.models import word2vec

    2.     Считайте данные о рецептах с помощью модуля csv

    with codecs.open('./edimdoma_dataset.csv', 'r') as f:

        reader = csv.reader(f)

        for line_id, line in enumerate(reader):

            if line_id == 0:

                continue

            doc = line[2]

            recipe_info = json.loads(doc)

     

     

    3.     Получите и распечатайте полученные категории рецептов

    category = recipe_info['recipeCategory'].strip() if 'recipeCategory' in recipe_info else 'NONE'

    categories.append(category)

    plt.figure(figsize=(12,8))

    ax = sns.countplot(categories)

    ax.set_xticklabels(ax.get_xticklabels(), rotation=40, ha="right")

    plt.tight_layout()

    plt.show()

     

    4.     Подготовьте входные данные для обучения нейронной сети, для этого:

    a.      Удалите слова из списка stopwords пакета nltk;

    stop_words = stopwords.words('russian')

    stop_words.extend(['.', ';', '!' ])

    print(u" ".join(stop_words))

    b.     Объедините некоторые инструкции в одну большую строку;

    c.      Проведите токенизацию текста по предложениям;

    d.     Проведите токенизацию предложений по словам;

    e.      Переведите полученные слова в нижний регистр;

     

    5.     Обучите модель word2vec, используя тексты рецептов. Для этого подготовьте следующую конструкцию:

     

    trained_word2vec = <train gensim word2vec with your sentences>

     

    6.     Задайте параметры нейронной сети, которая принимает на вход тексты рецептов и предсказывает их категорию:

    out = Dense(len(cat2id), activation='*')(out)

    model.compile("*", loss='*')

     

    7.     Разбейте данные на тренировочную и тестовую выборки, для этого реализуйте функцию get_batches(dataset, batch_count=64, batch_size=64, seq_size=20)

    8.     Инициируйте процесс обучения нейронной сети. Реализуйте код для вычисления тестового loss:
    for epoch in range(100):

    print("epoch: {}".format(epoch))

        losses = []

        for batch_x, batch_y in get_batches(train_dataset):

            loss = model.train_on_batch(batch_x, batch_y)

            losses.append(loss)

        print("train_loss: {}".format(np.mean(losses)))

     

    9.     Проверьте как ваша модель работает на тестовой выборке, для этого напишите функцию predict(query), выполняющую команду:

    preds = model.predict(np.expand_dims(batch, 0))[0]
    for x in sorted(enumerate(preds), key=lambda x: x[1], reverse=True)[:5]:

            print(u"{}: {}".format(cats[x[0]], x[1]))

     

    10.  Задачи для самостоятельной работы:

    a)     сделайте оптимизацию гиперпараметров нейронной сети. Попробуйте улучшить работу нейронной сети за счет слоев Batchnorm (https://arxiv.org/abs/1502.03167) и DropOut (https://www.cs.toronto.edu/~hinton/absps/JMLRdropout.pdf).

    b)     Обучите нейронную сеть, которая предсказывает время, необходимое для приготовления блюда по тексту рецепта. Используйте в качестве предсказываемого значения столбец «CookTime».

     

    Практическое задание №2.

    1.     Запустите jupyter notebook, создайте тетрадку в папке с данными, импортируйте модули, аналогичные практическому заданию №1

    2.     Считайте данные о рецептах с помощью модуля csv:

    with codecs.open(os.path.join(data_path, 'edimdoma_dataset.csv'), 'r') as f:

        reader = csv.reader(f)

    3.     Подготовьте данные для тренировки:

    a.     Объедините инструкции в текст
    text = "".join(instructions)[:300000]

    b.     Отсортируйте и сделайте словарь символов и соответствующих им id
    chars = sorted(list(set(text)))

    print('total chars:', len(chars))

    char2id = dict((c, i) for i, c in enumerate(chars))

    4.     Для задачи генерации текста создайте нейронную сеть со следующими параметрами:
                model = Sequential()

    <your code here>

    model.add(Dense(len(chars)))

    model.add(Activation('softmax'))

    optimizer = RMSprop(lr=0.01)

    model.compile(loss='categorical_crossentropy', optimizer=optimizer)

    5.     Разбейте данные на тренировочную и тестовую выборки, для этого реализуйте функцию get_batches(batch_count=128, batch_size=64)

    6.     Подготовьте функцию выбора символа:

    def sample_character(preds, temperature=1.0):

        preds = np.asarray(preds).astype('float64')

        preds = np.log(preds) / temperature

        exp_preds = np.exp(preds)

        preds = exp_preds / np.sum(exp_preds)

        probas = np.random.multinomial(1, preds, 1)

        return np.argmax(probas)

    7.     Инициируйте процесс обучения нейронной сети.

    a.      Реализуйте код для вычисления тренировочного loss:

    Создайте пустой массив и итеративно добавляйте полученные значения методом train_on_batch

    losses = []

    for batch_x, batch_y in get_batches():

        loss = model.train_on_batch(batch_x, batch_y)

        losses.append(loss)

    b.     Задайте параметры для генерации текста:

    if epoch > 40:

            max_gen_count = 500

            index = random.randint(0, len(text) - 100)

            for t in [0.1, 0.4, 0.7, 1]:

                sentence = text[index: index + seq_size]

                generated = sentence

    c.      Выведите получившиеся результаты сгенерированных предложений

    for step in range(max_gen_count):

                    batch = np.zeros((1, seq_size,))

                    for i in range(seq_size):

                        batch[0,i] = char2id[sentence[i]]

                    id = sample_character(model.predict_on_batch(batch)[0], t)

                    generated += chars[id]

                    sentence = sentence[1:] + chars[id]

                print(generated)

    8.     Задачи для самостоятельной работы:

    a.      Увеличить точность полученной модели. Для этого, воспользуйтесь продвинутыми техниками и нахождением подходящих гиперпараметров: таких как изменение размера последовательности, количества слоев сетей gru / lstm и т.д.

    b.     Решите задачу с помощью подхода, основанного на словах вместо символов, для получения красиво выглядящих текстов.



    • Раздел 2. Глубокое обучение

      Быстрые методы стохастического градиента (Поляка, Нестерова, AdaGrad, RMSProp, AdaDelta, Adam, Nadam). Проблема взрыва градиента и эвристика gradient clipping. Метод случайных отключений нейронов (Dropout). Интерпретации Dropout. Обратный Dropout и L2-регуляризация. Батч-нормализация. Функции активации ReLU и PReLU. Мини-батчи. BLAS3 операции.

      Обучение рекуррентных сетей. Backpropagation Through Time (BPTT). Слои RNN, GRU, LSTM. Их устройство и отличия.

      Свёрточные нейронные сети. Pooling. Zero-padding.  Понятие рецептивного поля.

      Sequence labelling, Named Entities Recognition (NER), Named Entities Linkage (NEL). Пакет Spacy.


      Практическое задание №3.

      1.      Решение задачи NER (Named Entity Recognition) – выделения непрерывных сущностей в тексте. Запустите jupyter notebook, создайте тетрадку и импортируйте модули аналогичные практическому заданию №1. Сущностями в задании послужат имена людей, наименование организаций и местоположения. Иными словами алгоритм должен понять, что участок текста “Нью Джерси” является местоположением, “Кофи Аннан” – персоной, а “ООН” – организацией.

      2.      Получите данные по ссылке: https://github.com/EuropeanaNewspapers/ner-corpora
      Пример получения данных с помощью библиотеки urllib:

      import urllib

      urllib.request.urlretrieve("https://raw.githubusercontent.com/EuropeanaNewspapers/ner-corpora/master/enp_FR.bnf.bio/enp_FR.bnf.bio", "enp_FR.bnf.bio")

      with open("enp_FR.bnf.bio") as f:

          text = f.read()

      3.      Разбейте слова и их тип при помощи метода split по символам переноса на новую строку '\n':

                  words = []

      types = []

      for item in text.split('\n'):

          item = item.strip()

          if len(item) == 0:

              continue

          [w, t] = item.split(' ')

          words.append(w)

          types.append(t)

      4.      Выделите уникальные типы используя и пронумеруйте их для идентификации:

      unique_types = list(set(types))

      type2id = {x:index for index, x in enumerate(unique_types)}

      print(type2id)

      5.      Подготовьте данные для обучения:

      a.      Подсчитайте количество наиболее встречающихся слов

      from collections import Counter

      word2count = Counter(words)

      MAX_WORD_COUNT = 30000

      top_words = [x[0] for x in sorted(word2count.items(), key=lambda x: x[1], reverse=True)][:MAX_WORD_COUNT]

      word2id = {x:index+1 for index, x in enumerate(top_words)}

      b.     Разбейте полученный набор данных на тренировочный и тестовый наборы

      train_dataset, test_dataset = train_test_split(list(zip(words, types)), train_size=0.7)

      c.      Напишите функции нахождения id слова

      def getWordId(w):

      return 0 if not w in word2id else word2id[w]

      d.     Реализуйте функцию gen_batches(dataset, batch_size=64, seq_size=32, batch_count=100):

      e.      Закодируйте полученные предложения

       def encode_text(sentence):

          words = sentence.split()

          result = np.zeros((len(words),))

          for i,w in enumerate(words):

              result[i] = getWordId(w)

          return result

      6.      Импортируйте модуль для демонстрации процесса обучения TensorBoard и фрэймворк tensorflow. Реализуйте функцию по созданию логов.

      def write_log(callback, names, logs, batch_no):

          for name, value in zip(names, logs):

              summary = tf.Summary()

              summary_value = summary.value.add()

              summary_value.simple_value = value

              summary_value.tag = name

              callback.writer.add_summary(summary, batch_no)

              callback.writer.flush()

      logs_dir = './logs'

      callback = TensorBoard(logs_dir)

      callback.set_model(model)

       

      7.      Инициируйте процесс обучения нейронной сети.

      a.      Реализуйте код для вычисления тренировочного loss:

      Создайте пустой массив и итеративно добавляйте полученные значения методом train_on_batch

      for epoch in range(100):

          losses = []

          for x,y in gen_batches(train_dataset, batch_count=32):

              loss = model.train_on_batch(x, y)

              losses.append(loss)

          train_loss = np.mean(losses)

      b.     Задайте параметры для генерации батчей и записывайте полученные результаты:

      losses = []

          for x,y in gen_batches(test_dataset, batch_count=32):

              loss = model.test_on_batch(x, y)

              losses.append(loss)

          test_loss = np.mean(losses)

          write_log(callback, ['train', 'test'], [train_loss, test_loss], epoch)

      8.      Протестируйте получившуюся модель:

      query = test_dataset[160:260]

      query_words = [x[0] for x in query]

      query_types = [x[1] for x in query]

      result = model.predict_on_batch(encode_text(" ".join(query_words)).reshape((1, -1)))[0]

      for index in range(result.shape[0]):

          w = query_words[index]

          true_type = query_types[index]

          pred_type = unique_types[np.argmax(result[index,:])]

          print("{}:\t{}\t{}".format(w, pred_type, true_type))

      1.     Задачи для самостоятельной работы:

      a.      Увеличить точность полученной модели. Для этого, воспользуйтесь продвинутыми техниками и нахождением подходящих гиперпараметров: таких как изменение размера последовательности, количества слоев сети.

      b.     Реализуйте модель со слоем CRF(https://github.com/Hironsan/keras-crf-layer)

       

      Практическое задание №4.

      1.     Создание сверточной нейронной сети (CNN) на наборе данных CIFAR-10 и визуализация полученных фильтров. Запустите jupyter notebook и создайте тетрадку.

      2.     Загрузите набор данных CIFAR-10, который содержит 32x32 цветных изображения из 10 классов: самолет, автомобиль, птица, кошка, олень, собака, лягушка, лошадь, корабль, грузовик

      from cifar import load_cifar10

      x_train,y_train,x_val,y_val,x_test,y_test = load_cifar10("cifar_data",channels_last=True)

      NUM_CLASSES = 10

      cifar10_classes = ["airplane", "automobile", "bird", "cat", "deer",

                         "dog", "frog", "horse", "ship", "truck"]

      3.     Подготовьте данные для обучения, нормализуйте их и преобразуйте метки классов в однозначно закодированные векторы. Используйте keras.utils.to_categorical:

      4.     Определите архитектуру сверточной нейронной сети:

      # import necessary building blocks

      from keras.models import Sequential

      from keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Activation, Dropout

      from keras.layers.advanced_activations import LeakyReLU

      5.     Создайте мини-сверточную сеть со следующей такой архитектурой:

      a.      входной уровень 3x3 свертки с 10 фильтрами и активация ReLU

      b.     3x3 pooling (или установите предыдущий шаг свертки на 3)

      c.      Dense слой с 100-нейронами и активация ReLU

      d.     10% dropout

      e.      Выходной dense слой.

       

      6.     Определите модель, которая принимает (None, 32, 32, 3) входные данные и прогнозирует (None, 10) выходные данные с вероятностями для всех классов. Простые сети прямой связи в Keras можно определить следующим образом:

      model = Sequential()  # start feed-forward model definition

      model.add(Conv2D(..., input_shape=(32, 32, 3)))  # first layer needs to define "input_shape"

      ...  # here comes a bunch of convolutional, pooling and dropout layers

      model.add(Dense(NUM_CLASSES))  # the last layer with neuron for each class

      model.add(Activation("softmax"))  # output probabilities

       

      7.     Обучите модель. Во время обучения вы должны наблюдать снижение заявленных потерь при обучении и валидации. Если потери на тренировках не уменьшаются с эпохами, следует пересмотреть определение модели и скорость обучения:

      INIT_LR = 5e-3  # initial learning rate

      BATCH_SIZE = 32

      EPOCHS = 10

      K.clear_session()  # clear default graph

      # don't call K.set_learning_phase() !!! (otherwise will enable dropout in train/test simultaneously)

      model = make_model()  # define our model

      # prepare model for fitting (loss, optimizer, etc)

      model.compile(

          loss='categorical_crossentropy',  # we train 10-way classification

          optimizer=keras.optimizers.adamax(lr=INIT_LR),  # for SGD

          metrics=['accuracy']  # report accuracy during training

      )

      # fit model

      model.fit(

          x_train2, y_train2,  # prepared data

          batch_size=BATCH_SIZE,

          epochs=EPOCHS,

          validation_data=(x_val, y_val),

          shuffle=True,

      )

       

      8.     Протестируйте получившуюся модель:

      y_pred_test = model.predict_proba(x_test)

      y_pred_test_classes = np.argmax(y_pred_test, axis=1)

      y_pred_test_max_probas = np.max(y_pred_test, axis=1)

       

      9.     Визуализируйте полученные моделью фильтры:

      cols = 8

      rows = 2

      fig = plt.figure(figsize=(2 * cols - 1, 3 * rows - 1))

      for i in range(cols):

          for j in range(rows):

              random_index = np.random.randint(0, len(y_test))

              ax = fig.add_subplot(rows, cols, i * rows + j + 1)

              ax.grid('off')

              ax.axis('off')

              ax.imshow(x_test[random_index, :])

              pred_label = cifar10_classes[y_pred_test_classes[random_index]]

              pred_proba = y_pred_test_max_probas[random_index]

              true_label = cifar10_classes[y_test[random_index]]

              ax.set_title("pred: {}\nscore: {:.3}\ntrue: {}".format(

                     pred_label, pred_proba, true_label

              ))

      plt.show()

      2.     Задачи для самостоятельной работы:

      a.      Увеличить точность полученной модели. Для этого, воспользуйтесь продвинутыми техниками и нахождением подходящих гиперпараметров: таких как изменение размера последовательности, количества слоев сети.

      b.     Реализуйте «Уменьшенную / ускоренную нейронную сеть», достигающую 80% точности с подробным анализом результатов, таких как карты значимости

       


      • Раздел 3. Глубокое обучение в NLP

        Обработка естественного языка (Natural Language Processing, NLP). Области применения NLP.

        Sequence-to-Sequence архитектура. Attention. Neural Turing Machine (NTM). Задачи автоматического машинного перевода текстов, обобщения текстов.

        Построение чат-ботов с помощью глубоких нейронных сетей. Обзор существующих подходов (Retrieval-Based, Generative Models). Понятия Open Domain, Closed Domain.

        Модель Transformer. Машинный перевод без корпуса параллельных текстов.


        Практическое задание №5.

        1.     Создание автокодировщиков, убирающих шум. Запустите jupyter notebook и создайте тетрадку.

        2.     Импортируйте следующие модули и загрузите набор данных lfw

        import numpy as np

        from lfw_dataset import fetch_lfw_dataset

        from sklearn.model_selection import train_test_split

        X, attr = fetch_lfw_dataset(use_raw=True,dimx=38,dimy=38)

        X = X.astype('float32') / 256.0

        img_shape = X.shape[1:]

        X_train, X_test = train_test_split(X, test_size=0.1,random_state=42)

         

        3.     Создайте автокодировщик, сложив несколько слоев. В частности, ваш кодер и декодер должны иметь глубину не менее 3-х слоев каждый. Вы можете использовать любую нелинейность, какую захотите, и любое количество скрытых нейронов в слоях:

        def build_deep_autoencoder(img_shape,code_size=32):

            H,W,C = img_shape

            encoder = keras.models.Sequential()

            encoder.add(L.InputLayer(img_shape))

            <Your code: define encoder as per instructions above>

            decoder = keras.models.Sequential()

            decoder.add(L.InputLayer((code_size,)))

            <Your code: define encoder as per instructions above>

            return encoder,decoder

         

        4.     Обучите получившиеся модели:

        encoder,decoder = build_deep_autoencoder(img_shape,code_size=32)

        inp = L.Input(img_shape)

        code = encoder(inp)

        reconstruction = decoder(code)

        autoencoder = keras.models.Model(inp,reconstruction)

        autoencoder.compile('adamax','mse')

         

        autoencoder.fit(x=X_train,y=X_train,epochs=32,

        validation_data=[X_test,X_test])

         

        5.     Протестируйте модели и убедитесь в том, что:

        a.      Модель сошлась. Некоторые архитектуры нуждаются в более чем 32 эпохах, чтобы сходиться. Они могут сильно колебаться, но в конечном итоге они станут достаточно хорошими. Вы можете тренировать свою сеть столько времени, сколько хотите.

        b.     Если вы обучаете модель из более чем 100 слоев и все еще не проходит порог, нужно начать с небольшого количества слоев (1-2) и увеличивать сложность модели небольшими шагами.

        c.      Вы используете любую комбинацию слоев (включая свертки, нормализацию и т.д.)

        d.     Используете следующий код для тестирования модели:

        reconstruction_mse = autoencoder.evaluate(X_test,X_test,verbose=0)

        assert reconstruction_mse <= 0.005, "Compression is too lossy. See tips below."

        assert len(encoder.output_shape)==2 and encoder.output_shape[1]==32, "Make sure encoder has code_size units"

        print("Final MSE:", reconstruction_mse)

        for i in range(5):

            img = X_test[i]

            visualize(img,encoder,decoder)

         

         

        6.     Превратите получившуюся модель в шумоподавляющий автоэнкодер. Cохранив модельную архитектуру, измените способ ее обучения. Существует много стратегий применения шума. Мы реализуем два популярных: добавление гауссовского шума и использование dropout:

        a.      Реализуйте добавление гауссовского шума:

        def apply_gaussian_noise(X,sigma=0.1):

           """

           adds noise from normal distribution with standard deviation sigma

          :param X: image tensor of shape [batch,height,width,3]

           """

         

          <your code here>       

            return X + noise

        b.     Тестирование шума:

        theoretical_std = (X[:100].std()**2 + 0.5**2)**.5

        our_std = apply_gaussian_noise(X[:100],sigma=0.5).std()

        assert abs(theoretical_std - our_std) < 0.01, "Standard deviation does not match it's required value. Make sure you use sigma as std."

        assert abs(apply_gaussian_noise(X[:100],sigma=0.5).mean() - X[:100].mean()) < 0.01, "Mean has changed. Please add zero-mean noise"

         

        7.     Автокодировщик имеет ряд удивительных побочных эффектов. Посмотрите на это в действии. Подавая на вход изображение, найдите похожие изображения в скрытом пространстве. Чтобы ускорить процесс поиска, используйте локально-чувствительное хеширование поверх закодированных векторов.  Используйте реализацию scikit-learn для простоты. В практическом сценарии вы можете использовать специализированные библиотеки для повышения производительности и настройки:

        a.      Внедрите функцию для нахождения похожих изображений

        def get_similar(image, n_neighbors=5):

            assert image.ndim==3,"image must be [batch,height,width,3]"

            code = encoder.predict(image[None])

            (distances,),(idx,) = lshf.kneighbors(code,n_neighbors=n_neighbors)

            return distances,images[idx]

         

        b.     Внедрите функцию для отображения похожих изображений

        def show_similar(image):

            distances,neighbors = get_similar(image,n_neighbors=11)

            plt.figure(figsize=[8,6])

            plt.subplot(3,4,1)

            plt.imshow(image)

            plt.title("Original image")

            for i in range(11):

                plt.subplot(3,4,i+2)

                plt.imshow(neighbors[i])

                plt.title("Dist=%.3f"%distances[i])

            plt.show()

         

        8.     Задачи для самостоятельной работы:

        a.      Увеличить точность полученной модели.

        b.     Реализуйте «Уменьшенную / ускоренную версию», с подробным анализом результатов

         

        Практическое задание №6

         

        1.     Запустите jupyter notebook, создайте тетрадку в папке с данными, импортируйте следующие модули

        import matplotlib.pyplot as plt

        %matplotlib inline

        import numpy as np

        2.     Считайте lfw датасет

        data,attrs = fetch_lfw_dataset(dimx=36,dimy=36)

        3.     Распечатайте случайную фотографию

        plt.imshow(data[np.random.randint(data.shape[0])], cmap="gray", interpolation="none")

        4.     Создайте нейронную сеть, которая отвечает за генерацию новых изображений

        CODE_SIZE = 256

         

        generator = Sequential()

        generator.add(L.InputLayer([CODE_SIZE],name='noise'))

        generator.add(L.Dense(10*8*8, activation='elu'))

         

        generator.add(L.Reshape((8,8,10)))

        generator.add(L.Deconv2D(64,kernel_size=(5,5),activation='elu'))

        generator.add(L.Deconv2D(64,kernel_size=(5,5),activation='elu'))

        generator.add(L.UpSampling2D(size=(2,2)))

        generator.add(L.Deconv2D(32,kernel_size=3,activation='elu'))

        generator.add(L.Deconv2D(32,kernel_size=3,activation='elu'))

        generator.add(L.Deconv2D(32,kernel_size=3,activation='elu'))

         

        generator.add(L.Conv2D(3,kernel_size=3,activation=None))

         

        5.     Создайте нейронную сеть, которая отвечает за классификацию сгенерированных изображений и настоящих

        discriminator = Sequential()

        discriminator.add(L.InputLayer(IMG_SHAPE))

        ….

        discriminator.add(L.Flatten())

        discriminator.add(L.Dense(256,activation='tanh'))

        discriminator.add(L.Dense(2,activation=tf.nn.log_softmax))

         

        6.     Натренируйте обе нейронные сети

        d_loss = -tf.reduce_mean(logp_real[:,1] + logp_gen[:,0])

        d_loss += tf.reduce_mean(discriminator.layers[-1].kernel**2)

        disc_optimizer =  tf.train.GradientDescentOptimizer(1e-3).minimize(d_loss,var_list=discriminator.trainable_weights)

        g_loss = ...

        gen_optimizer = tf.train.AdamOptimizer(1e-4).minimize(g_loss,var_list=generator.trainable_weights)

        s.run(tf.global_variables_initializer())

        7.     Примените натренированный генератор к случайному вектору и оцените качество результирующего изображения

            feed_dict = {

                real_data:sample_data_batch(100),

                noise:sample_noise_batch(100)

            }

           

            for i in range(5):

                s.run(disc_optimizer,feed_dict)

           

            s.run(gen_optimizer,feed_dict)

        8.     (Самостоятельная работа) Сделайте оптимизацию гиперпараметров и попробуйте уменьшить значение функции потерь на валидационной выборке