Python-matplotlib技术需求:实现仅决策边界动态更新、样本点静态的动画可视化
实现Delta规则决策边界动态动画的解决方案
嘿,我来帮你搞定这个动画需求!核心思路是让训练过程输出每一轮的权重,再用Matplotlib的动画工具只更新决策边界,样本点保持静态。下面是完整的修改方案和代码:
步骤1:改造训练函数,记录每轮权重
原来的sequential_deltaRule只返回最终权重,咱们得改成记录每一轮epoch后的权重,这样动画才能逐帧更新:
def sequential_deltaRule(X, W, T, maxEpoch): learningRate = 0.001 weights_history = [W.copy()] # 先存初始权重 currentEpoch = 1 while currentEpoch <= maxEpoch: for index, xCol in enumerate(X.T): Wdelta = -learningRate * np.dot(np.dot(W[0], xCol) - T[index], xCol.T) W = W + Wdelta weights_history.append(W.copy()) # 每轮训练完都存一下当前权重 currentEpoch += 1 return weights_history
步骤2:重构绘图逻辑,分离静态/动态部分
咱们先一次性画好样本点(保持静态),再用动画帧单独更新决策边界:
import numpy as np import matplotlib.pyplot as plt from matplotlib.animation import FuncAnimation # 保留你原来的generateData函数 def generateData(datapoints): n = datapoints mA, sigmaA = np.array([2.0, 1]), np.array([0.3, 0.3]) mB, sigmaB = np.array([-0.1, 0.0]), np.array([0.3, 0.3]) classA = (np.random.normal(size=(2, n)).T * sigmaA + mA).T classB = (np.random.normal(size=(2, n)).T * sigmaB + mB).T return classA, classB # 初始化静态样本点的绘图 def init_static_plot(classA, classB): plt.scatter(classA[0], classA[1], color='black', label='Class A') plt.scatter(classB[0], classB[1], color='red', label='Class B') plt.legend() ax = plt.gca() # 先创建一个空的决策边界线,后面逐帧更新它的数据 boundary_line, = ax.plot([], [], color='blue', label='Decision Boundary') ax.legend() return boundary_line, # 每帧更新决策边界的函数 def update_boundary(frame, weights_history, boundary_line): current_weights = weights_history[frame] x = np.linspace(-1.5, 3, 100) y = -(current_weights[1] * x + current_weights[0]) / current_weights[2] boundary_line.set_data(x, y) return boundary_line,
步骤3:整合所有代码,生成动画
把各部分拼起来,设置动画参数就能跑起来了:
# 生成样本数据 datapoints = 50 classA, classB = generateData(datapoints) # 准备训练数据(记得加偏置项!) data = np.vstack(( np.ones(datapoints*2), # 偏置项 np.hstack((classA[0], classB[0])), np.hstack((classA[1], classB[1])) )) # 初始化小范围随机权重 initial_weights = np.random.rand(1, 3) * 0.1 - 0.05 # 目标标签:Class A为1,Class B为-1 targets = np.hstack((np.ones(datapoints), -np.ones(datapoints))) # 获取每轮训练的权重历史 max_epochs = 20 weights_history = sequential_deltaRule(data, initial_weights, targets, max_epochs) # 创建动画 fig = plt.figure(figsize=(8, 6)) boundary_line, = init_static_plot(classA, classB) ani = FuncAnimation( fig, update_boundary, frames=len(weights_history), fargs=(weights_history, boundary_line), interval=300, # 每帧间隔300毫秒,可调整 blit=True # 只更新变化的部分,让动画更流畅 ) # 如果需要保存动画(需要安装ffmpeg) # ani.save('delta_rule_animation.mp4', writer='ffmpeg', fps=3) plt.show()
关键细节说明
- 静态样本点:在
init_static_plot里一次性绘制完成,后续动画帧不会修改这部分,保证样本点全程不动。 - 权重历史:每一轮epoch结束后保存当前权重,动画逐帧调用这些权重更新决策边界。
- 偏置项:必须给输入数据加全1的行,因为权重里的
current_weights[0]是偏置参数,这是Delta规则的基础要求哦。
运行这段代码后,你就能看到样本点静止不动,决策边界随着训练逐步调整的流畅动画啦!
内容的提问来源于stack exchange,提问作者David Krüger
相关产品推荐
相关产品推荐

