如何创建动画以可视化损失图以训练ML或DL算法?

时间:2019-08-04 14:38:14

标签: python matplotlib animation keras

我正在尝试根据历史创建损失图动画,以训练我的NN模型。这个想法在很大程度上受到GH Repo的启发,但是我无法弄清楚如何制作精美的动画,以便可以像DeepReplay包那样展示融合趋势。

def animate(i, loss, val_loss, title):
    data = loss.iloc[:int(i+1)]
    data2 = val_loss.iloc[:int(i+1)]

    plt.plot(np.array(data.index), data[title], color='b', label='Train Loss')    
    plt.plot(np.array(data2.index), data2[title], color='r', label='Test Loss')

    global flag
    if flag:
        plt.legend(loc='center right', fontsize='xx-large')
        flag = False

def create_loss_animation(model_type, loss_hist, val_loss_hist):
    fig = plt.figure(figsize=(20,20))

    plt.title(f'Loss on Train & Test', fontsize=25)
    plt.xlabel('Epoch', fontsize=20)
    plt.ylabel('Loss MSE for Sx-Sy & Sxy', fontsize=20)

    title = 'Loss MSE for Sx-Sy & Sxy'
    d = pd.DataFrame(loss_hist)
    d.columns = {title}
    x = np.array(d.index)
    y = np.array(d[title])
    loss = pd.DataFrame(y, x)
    loss.columns = {title}

    d2 = pd.DataFrame(val_loss_hist)
    d2.columns = {title}
    x2 = np.array(d2.index)
    y2 = np.array(d2[title])
    val_loss = pd.DataFrame(y2, x2)
    val_loss.columns = {title}

    Writer = animation.writers['ffmpeg']
    writer = Writer(fps=20, bitrate=1800)

    ani = matplotlib.animation.FuncAnimation(fig, animate, fargs=(loss, val_loss, title), repeat=True, interval=1000, repeat_delay=1000)
    ani.save(f'D:\\hi\\loss_animation_{model_type}_oneDataset.mp4', writer=writer)

我实现的结果如下: img

我的预期结果如下,但对于火车和测试数据的丢失趋势:

img

问题更新:

def animate(i, loss, val_loss, title):
    data = loss.iloc[:int(i+1)]
    data2 = val_loss.iloc[:int(i+1)]

    plt.plot(np.array(data.index), 'o-', label='Train Loss', color='b', markevery=[-1])    
    plt.plot(np.array(data2.index), 'o-', label='Test Loss', color='r', markevery=[-1])

    global flag
    if flag:
        plt.legend(loc='center right', fontsize='xx-large')
        flag = False

#def animate(i, l1, l2, loss, val_loss, title):
 #   data = loss.iloc[:int(i+1)]
  #  data2 = val_loss.iloc[:int(i+1)]

#     plt.plot(np.array(data.index), data[title], 'o-', label='Train Loss', color='b', markevery=[-1])    
#     plt.plot(np.array(data2.index), data2[title], 'o-', label='Test Loss', color='r', markevery=[-1])

   # l1.set_data(np.array(data.index), data[title])
    #l2.set_data(np.array(data2.index), data2[title])

    #return l1, l2

def create_loss_animation(model_type, loss_hist, val_loss_hist):
    #limYMin = np.min(l1.T[1])
    #limYMax = np.max(l1.T[1])
    #limXMin = np.min(l2.T[0])
    #limXMax = np.max(l2.T[0])
    fig = plt.figure(figsize=(20,20))

    plt.title(f'Loss on Train & Test', fontsize=25)
    plt.xlabel('Epoch', fontsize=20)
    plt.ylabel('Loss MSE for Sx-Sy & Sxy', fontsize=20)
    plt.gca().set_xlim([0, 50])
    plt.gca().set_ylim([0, 4])
    #plt.gca().set_xlim([limXMin, limXMax])
    #plt.gca().set_ylim([limYMin, limYMax])


    title = 'Loss MSE for Sx-Sy & Sxy'
    d = pd.DataFrame(loss_hist)
    d.columns = {title}
    x = np.array(d.index)
    y = np.array(d[title])
    loss = pd.DataFrame(y, x)
    loss.columns = {title}

    d2 = pd.DataFrame(val_loss_hist)
    d2.columns = {title}
    x2 = np.array(d2.index)
    y2 = np.array(d2[title])
    val_loss = pd.DataFrame(y2, x2)
    val_loss.columns = {title}

    Writer = animation.writers['ffmpeg']
    writer = Writer(fps=5, bitrate=1800)

    ani = matplotlib.animation.FuncAnimation(fig, animate, fargs=(loss, val_loss, title), repeat=True, interval=1000, repeat_delay=1000)
    ani.save(f'D:\\hi\\{zeit}_loss_animation_{model_type}_oneDataset.mp4', writer=writer)

如果有人可以帮助获得此动画,我将不胜感激,它会通过使用红色和蓝色点引领趋势,直到像我一样定义一个可执行函数来收敛。

1 个答案:

答案 0 :(得分:1)

这是我要怎么做:

x = np.linspace(0,100,100)
y1 = 1*np.exp(-x/20)
y2 = 1/(1+np.exp(-(x-20)/10))


fig, ax = plt.subplots()
l1, = ax.plot([], [], 'o-', label='func 1', markevery=[-1])
l2, = ax.plot([], [], 'o-', label='func 2', markevery=[-1])
ax.legend(loc='center right')
ax.set_xlim(0,100)
ax.set_ylim(0,1)


def animate(i):
    l1.set_data(x[:i], y1[:i])
    l2.set_data(x[:i], y2[:i])
    return (l1,l2)

ani = animation.FuncAnimation(fig, animate, frames=100, interval=10)

enter image description here

编辑:根据要求使用功能:

def animate(i, data1, data2, line1, line2):
    temp1 = data1.iloc[:int(i+1)]
    temp2 = data2.iloc[:int(i+1)]

    line1.set_data(temp1.index, temp1.value)
    line2.set_data(temp2.index, temp2.value)

    return (line1, line2)


def create_loss_animation(model_type, data1, data2):
    fig = plt.figure()
    plt.title(f'Loss on Train & Test', fontsize=25)
    plt.xlabel('Epoch', fontsize=20)
    plt.ylabel('Loss MSE for Sx-Sy & Sxy', fontsize=20)
    plt.xlim(min(data1.index.min(), data2.index.min()), max(data1.index.max(), data2.index.max()))
    plt.ylim(min(data1.value.min(), data2.value.min()), max(data1.value.max(), data2.value.max()))

    l1, = plt.plot([], [], 'o-', label='Train Loss', color='b', markevery=[-1])
    l2, = plt.plot([], [], 'o-', label='Test Loss', color='r', markevery=[-1])
    plt.legend(loc='center right', fontsize='xx-large')

    Writer = animation.writers['ffmpeg']
    writer = Writer(fps=5, bitrate=1800)

    ani = matplotlib.animation.FuncAnimation(fig, animate, fargs=(data1, data2, l1, l2), repeat=True, interval=1000, repeat_delay=1000)
    ani.save(f'{model_type}.mp4', writer=writer)

# create datasets
x = np.linspace(0,150,50)
y1 = 41*np.exp(-x/20)
y2 = 35*np.exp(-x/50)

my_data_number_1 = pd.DataFrame({'x':x, 'value':y1}).set_index('x')
my_data_number_2 = pd.DataFrame({'x':x, 'value':y2}).set_index('x')

create_loss_animation('test', my_data_number_1, my_data_number_2)

enter image description here