Прежде чем начать эту статью, давайте взглянем на историю:
People's Daily Online Согласно сообщению Британской радиовещательной корпорации от 25 октября, произведение искусства, созданное с помощью искусственного интеллекта, было успешно продано с аукциона по высокой цене в 432 000 долларов США (около 3 миллионов юаней).
Это может показаться незаметной новостью, но на самом деле она имеет далеко идущие последствия: люди начинают осознавать художественную ценность компьютерного творчества, а те художники, которые самоуспокаиваются и думают, что их не заменит искусственный интеллект, дрожать.
Как выглядит эта работа, созданная искусственным интеллектом, и что в ней особенного?
Что ж, для неспециалиста вроде меня это не очень хорошо, но это не значит, что искусственный интеллект не может. Вы должны знать, что когда AlphaGo впервые дебютировал, он осмелился бросить вызов второсортным игрокам, таким как Фань Хуэй, а затем бросить вызов лучшему игроку Ли Шиши. игроки. Однако это еще не конец, AlphaGo Zero больше не изучает человеческий шахматный репертуар, и полностью за счет самообучения, сокрушения AlphaGo Master и общения с людьми-шахматистами это так же просто, как убить муравья.
Поэтому, хотя первая работа, созданная искусственным интеллектом, подобна призраку, рисующему персиковый шарм, ее потенциал безграничен.
Итак, далее мы обсудим, как создать известную картину? Нет нет.
Создать картину не так-то просто. Картина под названием «Портрет Эдмунда Беллами» была создана парижской арт-группой «Очевидно» с использованием технологии искусственного интеллекта на основе портретных данных с 14 по 20 век.
У нас пока нет условий для создания ИИ-картины, но мы можем начать с основ, генерируя рукописные числа. Написанные от руки числа слишком хорошо знакомы изучающим машинное обучение. Теперь, когда мы старые друзья, давайте начнем!
Сначала просмотритеГенеративно-состязательные сети в действии [1]: введение«Содержание этой статьи, GAN состоит из генератора и дискриминатора. Для простоты мы выбираем простую двухслойную нейронную сеть для реализации генератора и дискриминатора.
Строитель
Реализовать генератор несложно.Топология полносвязной сети, которую мы берем: 100 --> 128 --> 784, а конечный результат – 784, поскольку набор данных MNIST состоит из изображений в градациях серого размером 28 x 28 пикселей. код показывает, как показано ниже:
G_W1 = tf.Variable(initializer([100, 128]), name='G_W1')
G_b1 = tf.Variable(tf.zeros(shape=[128]), name='G_b1')
G_W2 = tf.Variable(initializer([128, 784]), name='G_W2')
G_b2 = tf.Variable(tf.zeros(shape=[784]), name='G_b2')
theta_G = [G_W1, G_W2, G_b1, G_b2]
def generator(z):
G_h1 = tf.nn.relu(tf.matmul(z, G_W1) + G_b1)
G_log_prob = tf.matmul(G_h1, G_W2) + G_b2
G_prob = tf.nn.sigmoid(G_log_prob)
return G_prob
дискриминатор
Дискриминатор как раз наоборот, принимает изображение MNIST в качестве входных данных и возвращает скаляр, представляющий вероятность реального изображения, код выглядит следующим образом:
D_W1 = tf.Variable(initializer(shape=[784, 128]), name='D_W1')
D_b1 = tf.Variable(tf.zeros(shape=[128]), name='D_b1')
D_W2 = tf.Variable(initializer(shape=[128, 1]), name='D_W2')
D_b2 = tf.Variable(tf.zeros(shape=[1]), name="D_W2")
theta_D = [D_W1, D_W2, D_b1, D_b2]
def discriminator(x):
D_h1 = tf.nn.relu(tf.matmul(x, D_W1) + D_b1)
D_logit = tf.matmul(D_h1, D_W2) + D_b2
D_prob = tf.nn.sigmoid(D_logit)
return D_prob, D_logit
алгоритм обучения
в диссертацииarXiv: 1406.2661, 2014Псевдокод алгоритма обучения приведен в:
Оптимизатор в TensorFlow может выполнять только минимизацию, потому что для максимизации функции потерь мы ставим перед функцией потерь, заданной псевдокодом, знак минус.
D_loss = -tf.reduce_mean(tf.log(D_real) + tf.log(1. - D_fake))
G_loss = -tf.reduce_mean(tf.log(D_fake))
Затем определите оптимизатор:
# 仅更新D(X)的参数, var_list=theta_D
D_solver = tf.train.AdamOptimizer().minimize(D_loss, var_list=theta_D)
# 仅更新G(X)的参数, var_list=theta_G
G_solver = tf.train.AdamOptimizer().minimize(G_loss, var_list=theta_G)
Наконец, повторите и обновите параметры:
for it in range(60000):
X_mb, _ = mnist.train.next_batch(mb_size)
_, D_loss_curr = sess.run([D_solver, D_loss], feed_dict={X: X_mb, Z: sample_Z(mb_size, Z_dim)})
_, G_loss_curr = sess.run([G_solver, G_loss], feed_dict={Z: sample_Z(mb_size, Z_dim)})
Весь процесс на самом деле похож на предыдущий алгоритм глубокого обучения, и его очень легко понять. Алгоритм работает? Мы можем отобразить рукописные цифры, сгенерированные во время итерации:
Что ж, хотя результат немного неудовлетворителен, это почти глиф рукописных чисел, и с итерацией он все ближе и ближе к рукописным числам, можно сказать, что алгоритм GAN все еще эффективен.
резюме
Простую сеть GAN можно создать всего несколькими строками кода, и кажется, что создать картину несложно. Не будьте столь оптимистичны, на самом деле в сети GAN еще много ям, например, в процессе итерации появились следующие подсказки:
Iter: 9000
D loss: nan
G_loss: nan
Из кода видно, что сеть GAN по-прежнему использует метод градиентного спуска для итеративного решения параметров. Градиентный спуск инициируется, чтобы выбрать направление, которое уменьшает потери определенной проблемы, но у нас нет способа гарантировать, что сеть GAN может войти в состояние равновесия Нэша, что является многомерной невыпуклой целью оптимизации. Сеть пытается минимизировать цель невыпуклой оптимизации на следующих шагах, что может привести к колебаниям вместо сходимости к базовой формальной цели.
Также есть проблемы с коллапсом модели, счетчиками, углами и глобальной структурой.Для решения этих проблем нужно использовать некоторые специальные приемы и методы, о которых мы поговорим позже, когда будем углубляться в различные модели GAN.
Полный код этой статьи см. по адресу:GitHub.com/mogo Web/голодание…