Написано впереди: Чтобы визуализировать процесс машинного обучения и сохранить его, я хочу использовать его напрямую.
Чтобы сохранить движущуюся картину, я ссылался на множество материалов в тот период, процесс был достаточно сложным, поэтому я захотел его записать. Конечно, эта статья также относится ко многим другим статьям в Интернете, и спасибо тем, кто любит делиться
, а ссылки даны в References. Весь код организован вGitHub.
Получите эффект первым!
0. Предварительная подготовка
Установитьи
. Конкретная установка может быть прямо на официальном сайте, Если у вас возникнут какие-либо проблемы, вы можете в основном найти ответ в Интернете, поэтому я не буду его здесь представлять. Здесь просто использовать
Сгенерируйте некоторые тестовые данные, если они правы
незнакомый, ссылкаОфициальное руководство по началу работы с NumPy (перевод), если правильно
незнакомый, ссылкаОсновные операции Matplotlib. Конечно, если вы хотите сэкономить
еще один инструментImageMagick, просто следуйте официальным инструкциям по установке, обязательно введите команду
magick
Есть ответ. При использованиикакой-то тип
Пожалуйста, настройте переменные среды глобально, чтобы избежать
команда не найдена в .
1. Нарисуйте базовую анимацию
Убедитесь, что вы установилиImageMagickИ продолжить, если доступно, иначе код будет работать.
Есть два способа рисовать анимацию
1.1 Сброс и перерисовка
Сброс и перерисовка в основном предназначены для обновления значения исходной графики каждый раз для достижения эффекта анимации рисования.
- импортировать базовую библиотеку
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import animation
- Сгенерировать данные, нарисовать исходный график
fig, ax = plt.subplots()
x = np.arange(0, 2 * np.pi, 0.01)
line0 = ax.plot(x, np.cos(x))
line, = ax.plot(x, np.sin(x))
Обратите внимание, что заявление здесьсередина
,
Не меньше, как бы для соответствия типу при обновлении значения. Я не знаю, я надеюсь, что вы можете дать некоторые указатели.
- Определите начальную функцию и функцию обновления
def init():
line.set_ydata(np.sin(x))
return line,
def animate(i):
line.set_ydata(np.sin(x + i / 10.0))
return line,
На самом деле просто обновитьЗначение координат.
- выполнить анимацию
animation = animation.FuncAnimation(fig=fig, func=animate, frames=100, init_func=init, interval=20, blit=False)
Параметры этой функции можно увидеть в исходном коде и во введении на официальном сайте.нарисовать рамку, всего
Рамка.
- спасти
animation.save('resetvalue.gif', writer='imagemagick')
Вот прямое сохранение какФормат просто отличный.
- Показать гифку
plt.show()
Эффект сгенерированного изображения показан на рисунке:
1.2 Стереть и перерисовать
По сравнению с предыдущим методом этот метод заключается в прямом стирании без использования каких-либо координат предыдущего времени, а затемГрафика вверх.
- импортировать базовую библиотеку
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import animation
- Сгенерировать данные, нарисовать исходный график
fig, ax = plt.subplots()
x = np.arange(0, 2 * np.pi, 0.01)
ax.plot(x, np.cos(x))
Здесь в этом нет необходимости, потому что этот способ не зависит от предыдущего графа.
- Определите начальную функцию и функцию обновления
def init():
return ax.plot(x, np.sin(x))
def animate(i):
try:
ax.lines.pop(1)
except Exception:
pass
line = ax.plot(x, np.sin(x + i / 10.0), 'r')
return line,
Про инициализацию и говорить нечего, на самом деле инициализировать не надо, если временной интервал слишком мал, то эффект в принципе незаметен. Давайте представимax.lines.pop(1)
Функция фразы «стереть». здесьможно понимать как хранение
Стопка изображений вверху, спереди
Рисуется функция косинуса, а вторая линия рисуется во время инициализации, поэтому индекс
Функция синуса
и затем приступайте к следующему рисунку. Так выполнить
line = ax.plot(x, np.sin(x + i / 10.0), 'r')
- следовать за
animation = animation.FuncAnimation(fig=fig, func=animate, frames=100, init_func=init, interval=20, blit=False)
animation.save('redraw.gif', writer='imagemagick')
plt.show()
нет разницы
Эффект сгенерированного изображения показан на рисунке:
2. Визуализация процесса машинного обучения
Приведенных выше знаний в принципе достаточно, но они все-таки не практичны. Если вы не изучаете машинное обучение, у вас действительно может быть вышеуказанная основа, и этот раздел можно пропустить. Однако, если вы хотите научиться машинному обучению, вот небольшой пример, который даст вам более четкое представление об изменениях данных в процессе машинного обучения. Но здесь сосредоточено только на рисовании, часть справочника по машинному обучению.Начало работы с машинным обучением с TensorFlow
Опять же, в качестве примера возьмем линейную регрессию.
исходный код
# coding: utf-8
from __future__ import print_function
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from scipy.interpolate import spline
train_X = np.linspace(0, 10, 50)
noise = np.random.normal(0, 1, train_X.shape)
train_Y = train_X * 1 - 2 + noise
X = tf.placeholder(tf.float32)
Y = tf.placeholder(tf.float32)
W = tf.Variable(-1., name="weight")
b = tf.Variable(1., name="bias")
activation = tf.add(tf.multiply(X, W), b)
learning_rate = 0.0001
cost = tf.reduce_sum(tf.pow(activation - Y, 2))
optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)
training_epochs = 20
display_step = 10
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for epoch in range(training_epochs):
for (x, y) in zip(train_X, train_Y):
sess.run(optimizer, feed_dict={X: x, Y: y})
if epoch < 10 or epoch % display_step == 0:
c_tmp = sess.run(cost, feed_dict={X: train_X, Y: train_Y})
W_tmp = sess.run(W)
b_tmp = sess.run(b)
activation_tmp = sess.run(activation, feed_dict={X: train_X})
print("Epoch: %04d" % (epoch + 1), "cost=", "{:.9f}".format(c_tmp), "W=", W_tmp, "b=", b_tmp)
print("Optimization Finished!")
print("cost=", sess.run(cost, feed_dict={X: train_X, Y: train_Y}), "W=", sess.run(W), "b=", sess.run(b))
Приведенный выше код пояснять не буду, для удобства тестирования количество итераций уменьшено. Далее будем расширяться на основе вышеизложенного.
Давайте начнем с визуализации и сначала извлечем данные, которые мы считаем полезными. Поскольку после тестирования предыдущая вариация относительно велика, чтобы сделать диаграмму наглядной, намеренно выполняется неравномерная выборка.
c_trace = []
W_trace = []
b_trace = []
activation_trace = []
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for epoch in range(training_epochs):
for (x, y) in zip(train_X, train_Y):
sess.run(optimizer, feed_dict={X: x, Y: y})
if epoch < 10 or epoch % display_step == 0:
c_tmp = sess.run(cost, feed_dict={X: train_X, Y: train_Y})
W_tmp = sess.run(W)
b_tmp = sess.run(b)
activation_tmp = sess.run(activation, feed_dict={X: train_X})
print("Epoch: %04d" % (epoch + 1), "cost=", "{:.9f}".format(c_tmp), "W=", W_tmp, "b=", b_tmp)
c_trace.append(c_tmp)
W_trace.append(W_tmp)
b_trace.append(b_tmp)
activation_trace.append(activation_tmp)
print("Optimization Finished!")
print("cost=", sess.run(cost, feed_dict={X: train_X, Y: train_Y}), "W=", sess.run(W), "b=", sess.run(b))
Ссылаясь на предыдущий небольшой пример, заполните данные и сделайте движущуюся картинку.
fig, ax = plt.subplots()
l1 = ax.scatter(train_X, train_Y, color='red', label=r'$Original\ data$')
ax.set_xlabel(r'$X\ data$')
ax.set_ylabel(r'$Y\ data$')
def update(i):
try:
ax.lines.pop(0)
except Exception:
pass
line, = ax.plot(train_X, activation_trace[i], 'g--', label=r'$Fitting\ line$', lw=2)
return line,
ani = animation.FuncAnimation(fig, update, frames=len(activation_trace), interval=100)
ani.save('linearregression.gif', writer='imagemagick')
plt.show()
Результаты, как показано ниже:
тогда поставьФункция также добавляется и отображается в конце.
def update(i):
try:
ax.lines.pop(0)
except Exception:
pass
line, = ax.plot(train_X, activation_trace[i], 'g--', label=r'$Fitting\ line$', lw=2)
if i == len(activation_trace) - 1:
twinax = ax.twinx()
twinax.plot(np.linspace(0, 10, np.size(c_trace)), c_trace, 'b', label='Cost line', lw=2)
return line,
Видно, что линии очень четкие, и вы можете использовать это в это время.Плавный переход.
def update(i):
try:
ax.lines.pop(0)
except Exception:
pass
line, = ax.plot(train_X, activation_trace[i], 'g--', label=r'$Fitting\ line$', lw=2)
if i == len(activation_trace) - 1:
xnew = np.linspace(0, 10, np.max(c_trace) - np.min(c_trace))
smooth = spline(np.linspace(0, 10, np.size(c_trace)), c_trace, xnew)
twinax = ax.twinx()
twinax.set_ylabel(r'Cost')
twinax.plot(xnew, smooth, 'b', label=r'$Cost\ line$', lw=2)
return line,
На самом деле это правильновыборка в этом интервале. Добавить к
np.max(c_trace) - np.min(c_trace)
точки для проведения линии.
Добавьте легенду.
def update(i):
try:
ax.lines.pop(0)
except Exception:
pass
line, = ax.plot(train_X, activation_trace[i], 'g--', label=r'$Fitting\ line$', lw=2)
plt.legend(handles=[l1, line], loc='upper center')
if i == len(activation_trace) - 1:
ax.text(6, -2, 'Cost: %s' % c_trace[i], fontdict={'size': 16, 'color': 'r'})
xnew = np.linspace(0, 10, np.max(c_trace) - np.min(c_trace))
smooth = spline(np.linspace(0, 10, np.size(c_trace)), c_trace, xnew)
twinax = ax.twinx()
twinax.set_ylabel(r'Cost')
costline, = twinax.plot(xnew, smooth, 'b', label=r'$Cost\ line$', lw=2)
plt.legend(handles=[l1, line, costline], loc='upper center')
return line,
Детали данных обрабатываются ниже.
learning_rate = 0.001
training_epochs = 500
display_step = 40
можно увидеть,Функция не является строго убывающей, Мы используем алгоритм градиентного спуска, чтобы найти оптимум, поэтому проблема заключается в скорости обучения, и почему это также проблема, на которую следует обратить внимание в машинном обучении. Кроме того, вы можете попробовать продолжать увеличивать скорость обучения, чтобы увидеть, что интересного будет происходить?
Мы корректируем скорость обучения, чтобы0.0001
Будут получены следующие результаты:
На самом деле результат, который вы видите, может не совсем совпадать с исходной функцией. И когда вы постоянно настраиваете параметры тренировки, вы обнаружите, что степень соответствия не каждый раз кажется очень хорошей. Причина на самом деле дополнительные помехи Что касается того, почему помехи вызывают это, это выходит за рамки этой статьи. Ну, на этом этапе вы должны быть в состоянии нарисовать свой собственныйНу давай же.
Подробности смотрите в исходном кодеGitHub
3. Резюме
Если вы потратите время на то, чтобы разобраться в мелких деталях, это сэкономит время, ведь проблема может привести к другим проблемам, о которых стоит подумать. Подключайтесь больше, думайте больше.