去掉一些细节,思路分两大模块。第一模块,初始化网络标签权重和待训练权重;第二模块,利用权重依次计算输出、成本、loss,然后更新。也就是第一模块是初始化某些参数,第二模块是调用工具去训练参数。
注意,下面两个引用模块只保留了关键步骤,无法构成完整的训练。如ITER等细节详见后面的输入代码块
第一模块
初始化待训练网络参数:
W = init_net.UniformFill([], "W", shape=[1,2], min=-1, max=1.)
B = init_net.ConstantFill([], "B", shape=[1], value=0.0)初始化标签参数:实际上训练是有标签的,可以不要
W_gt = init_net.GivenTensorFill([], "W_gt", shape=[1,2], values=[2.0, 1.5])
B_gt = init_net.GivenTensorFill([], "B_gt", shape=[1], values=[0.5])
有了Weight和Bias,我们就可以用最简单的 y = AW+b 去计算输出。
第二模块
用权重计算输出y,y与标签y_gt对比计算出成本dist,成本dist计算loss,最后将loss更新到W、B、X(X是输入,为什么要更新)
计算y:
Y_pred = X.FC([W, B], "Y_pred")
计算标签的y_gt:
Y_gt = X.FC([W_gt, B_gt], "Y_gt")
# Y_gt不需要反向传播,因此通过StopGradient,让auto differentiation algorithm忽略这部分
Y_gt = Y_gt.StopGradient([], "Y_gt")计算成本dist:
# loss是L2正则化,对每个变量计算loss后,计算batch内全部loss值的平均值
dist = train_net.SquaredL2Distance([Y_gt, Y_pred], "dist")计算loss:
loss = dist.AveragedLoss([], ["loss"])更新:
gradient_map = train_net.AddGradientOperators([loss])
完整输入
# coding=utf-8
import numpy as np
from caffe2.python import core, workspace, net_drawer, cnn, visualize
from IPython import display
from matplotlib import pyplot
from PIL import Image
#声明计算图
init_net = core.Net("init")
# ground true paraments
W_gt = init_net.GivenTensorFill([], "W_gt", shape=[1,2], values=[2.0, 1.5])
B_gt = init_net.GivenTensorFill([], "B_gt", shape=[1], values=[0.5])
# 常量one,用于weight更新
ONE = init_net.ConstantFill([], "ONE", shape=[1], value=1.)
# iter is the iteration count
ITER = init_net.ConstantFill([], "ITER", shape=[1], value=0, dtype=core.DataType.INT32)
W = init_net.UniformFill([], "W", shape=[1,2], min=-1, max=1.)
B = init_net.ConstantFill([], "B", shape=[1], value=0.0)
print("create init net")
'''
主要的训练网络定义如下。我们将通过多个步骤展示创建的内容。
- 产生损失的正向传播
- 通过自动求导产生的反向传播
- 参数更新部分,这是一个标准的SGD
'''
train_net = core.Net("train")
X = train_net.GaussianFill([], "X", shape=[64,2], mean=0.0, std=1.0, run_once=0)
Y_gt = X.FC([W_gt, B_gt], "Y_gt")
# add noise to ground true
noise = train_net.GaussianFill([], "noise", shpae=[64,1], mean=0.0, std=1.0, run_once=0)
Y_noise = Y_gt.Add(noise, "Y_noise")
# Y_noise不需要反向传播,因此通过StopGradient,让auto differentiation algorithm忽略这部分
Y_noise = Y_noise.StopGradient([], "Y_noise")
Y_pred = X.FC([W, B], "Y_pred")
# loss是L2正则化,对每个变量计算loss后,计算batch内全部loss值的平均值
dist = train_net.SquaredL2Distance([Y_noise, Y_pred], "dist")
loss = dist.AveragedLoss([], ["loss"])
'''
网络可视化,主要有4部分
-批次生成的X(GaussianFill生成X)
-使用Wgt,Bgt,FC operator生成ground truth
-使用W、B预测
-比较输出,计算损失
'''
gradient_map = train_net.AddGradientOperators([loss])
graph = net_drawer.GetPydotGraph(train_net.Proto().op, "train", rankdir="LR")
display.Image(graph.create_png(), width=800) #这里display没有输出,图像时byte类型,以下面的方式保存了
from io import BytesIO
image = Image.open(BytesIO(graph.create_png()))
image.save('F:\\testCaffe2\\1.png')
输出