参考:https://zhuanlan.zhihu.com/p/34701319。
本博客使用的是python3,参考网站使用的是py2。代码有部分不同
复习大纲:
- 准备工作:整理数据(创建文件夹,下载数据)——加载数据——定义模型——定义表现观测函数——选择计算损失的方式——定义计算模型的准确性的方式——将所有梯度运算符添加到模型——定义各种参数——定义日志记录函数
- 将准备的东西拼一块,包括数据、模型、添加梯度等等。。
- 可视化
- 正式训练,一次或者多次,绘制训练结果(loss、train_acc)
- 保存模型参数
- 加载训练好的模型,测试
准备工作:
- 设置路径:os.path.join(‘根path’,‘子path1’,‘子path2’。。。‘最终指向path’)
- 判断文件是否存在:os.path.exist(‘path’)
- 创建路径:os.path.makedirs(‘path’)
- 下载文件:file = request.get(‘url’, stream=true)
- 提取下载的文件:file = zipFile.ZipFile(‘file_path’) or zipFile.ZipFile(StringIO.StringIO(file.content))
- 解压文件: file.extractall(‘unzip_path’)
加载mdb数据:
- data=model.TensorProtosDBInput(self, unused_blob_in, blob_out, batch_size, db, db_type)
- 数据处理:model.Cast(data_in, “tag”, to=core.DataType.Float)/Scale(in, out, scale=计算方式如float(1./256))
- 取消梯度计算(当数据是原始输入时,不需要计算梯度,节省时间):model.StopGradient(in, out)
构建网络:
- 卷积层:conv = brew.conv(model, data, ‘该层标签’, dim_in=, dim_out, kernel=)
- 最大池化层:pool = brew.max_poo(model, 上一层的输出,’该层标签’,kernel = ,stride=)
- 全连接:fc = brew.fc(model,上一层的输出,‘标签’,dim_in=输入维度c*h*w,dim_out=输出维度,一定是一列)
- softmax = brew.softmax(model, 上一层的输出,’标签’)
表现观测:
- accuracy = brew.accuracy(model, [softmax, label], ‘标签’)
计算loss及使用反向传播:
- 交叉熵计算:xent = model.LabelCrossEntropy([softmax, label], xent)
- 平均loss:loss = model.AverageLoss(交叉熵,”标签”)
- 也需要给train添加accuracy
- 添加计算梯度功能:model.AddGradientOperators([loss])
- 获得ITER:ITER = brew.iter(model, “iter”)
- 计算LR:model.LearningRate(ITER, “LR”, base_lr=-0.1, policy=”step”, stepsize=1, gamma=0.999)
- 设置梯度更新常量,只要设置成1就可以:one = model.param_init_net.ConstantFill([], “ONE”, shape=[1], value=1.0)
- 更新权重:for param in model.params:
- param_grad = model.param_to_grad[param]
- # 设置更新梯度的方式 param = param + param_grad * LR
- model.WeightedSum([param, ONE, param_grad, LR], param)
打印模型某层参数(blob):
- model.Print(‘标签’,[], to_file:是否保存到本地)
- 统计参数: model.Summarize(param, [], to_file=1)
实战:
这里都是初始化网络,只是架构,一切准备就绪。
train:初始化train网络类train_class——给trian_class添加输入——在train_class中创建网络,返回网络输出——设置trian_class的loss、gradient、反向传播——输出参数结果(acc、loss)
test:初始化test网络类test_class(init_param=false)——给class添加输入——在class中创建网络——计算输出——显示结果
deploy:初始化deploy网络类deploy_class——在class中创建网络
def main():
arg_scope = {"order": "NCHW"}
train_model = model_helper.ModelHelper(name="mnist_train", arg_scope=arg_scope)
data, label = AddInput(
train_model, batch_size=64,
db=os.path.join(data_folder, 'mnist-trian-nchw-lmdb'),
db_type='lmdb'
)
softmax = LeNetModel(train_model, data)
AddTrainingOperators(train_model, softmax, label)
AddBookkeepingOperators(train_model)
test_model = model_helper.ModelHelper(name="mnst_test", arg_scope=arg_scope,init_params=False)
data, label = AddInput(test_model,batch_size=64,
db=os.path.join(data_folder,'mnist-test-nchw-lmdb'),
db_type='lmdb')
LeNetModel(test_model,data)
softmax = LeNetModel(test_model, data)
AddAccuracy(test_model, softmax, label)
deploy_model = model_helper.ModelHelper(name="mnist_deploy", arg_scope=arg_scope,init_params=False)
LeNetModel(deploy_model,data)
模型可视化:
- graph = net_drawer.GetPydotGraph(model.net.Proto().op, “name”, rankdir=”LR”)
- display.Image(graph.create_png(), width=)
- 简化图,图的左半部分是正向传播,图的右半部分是反向传播,右边是一组参数更新和汇总 graph = net_drawer.GetPydotGraphMinimal(model.net.Proto().op, “name”, rankdir=”LR”, minimal_dependency=True)
- 显示序列化协议缓冲区,类似caffe的net文件:
print(str(train_model.param_init_net.Proto())[:400] + '\n...')
运行网络:
train:在workspace中初始化网络——在ws中创建网络——ws中训练网络——获取训练结果acc、loss,并绘制——保存权重
test:在workspace中初始化网络——在ws中创建网络——ws中测试网络性能——获取测试结果并绘制
预加载:
train:
#初始化参数
workspace.RunNetOnce(train_model.param_init_net)
#创建网络
workspace.CreateNet(train_model.net)
total_iter = 200
accuracy = np.zeros(total_iter)
loss = np.zeros(total_iter)
#训练网络参数
for i in range(total_iter):
workspace.RunNet(train_model.net.Proto().name)
#记录训练结果
accuracy[i] = workspace.FetchBlob('accuracy')
loss[i] = workspace.FetchBlob('loss')
#绘制loss和acc
pyplot.plot(loss, 'b')
pyplot.plot(accuracy, 'r')
pyplot.legend(('Loss', 'Accuracy'), loc='upper right')
#绘制特征图
pyplot.figure()
conv = workspace.FetchBlob('conv1')
#此时conv是n*15*h*W的,通道数=15,我们只需要看一个channel,因此将这一维reshape成1
shape = list(conv.shape)
shape[1] = 1
# We can look into any channel. This of it as a feature model learned
conv = conv[:,15,:,:].reshape(shape)
_ = visualize.NCHW.ShowMultiple(conv)
test:
workspace.RunNetOnce(test_model.param_init_net())
workspace.CreateNet(test_model.net, overwrite=True)
for i in range(100):
workspace.RunNet(test_model.net.Proto().name)
预加载模型训练:
#预加载模型测试
#这里偷懒了,用之前训练或测试用的数据。正常来说,图像被测试前,需要经过 换通道、转成特定格式、resize、归一化进行处理
blob = workspace.FetchBlob(“data”)
workspace.ResetWorkspace(root_folder)
print(“check if any blob left in workspace”)
#加载模型,加载后不需要再初始化,也不需要在createNet
predict_net = pe.prepare_prediction_net(os.path.join(root_folder, “mnist_model.minidb”), “minidb”)
workspace.FeedBlob(“data”, blob)
workspace.RunNetOnce(predict_net)
softmax = workspace.FetchBlob(“softmax”)
#绘制测试结果
pyplot.figure()
_ = pyplot.plot(softmax[0], ‘ro’)
pyplot.title(‘Prediction for the first image’)
os:。。。
今天的文章caffe2学习——0223——使用MNIST数据集训练LeNet-5「建议收藏」分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/88839.html