learn_numpy_python
dot = np.dot(x1,x2)
矩阵点积,一维是向量内积,多维是矩阵乘法运算,矩阵相乘一般采用dot
,而元素对应相乘一般使用*
。1
2
3
4
5outer = np.outer(a,b) #矩阵点乘 a = [a0, a1, ..., aM],b = [b0, b1, ..., bN]
[[a0*b0 a0*b1 ... a0*bN ]
[a1*b0 .
[ ... .
[aM*b0 aM*bN ]]mul = np.multiply(x1,x2)
#对应元素相乘。图像的表示方法是
1797 × 64
picture_data = data.reshape(-1,8,8,1)
-1表示不知道,两个8表示8行8列,1表示一维空间(彩色是在处理的时候是三维空间RGB),整短代码就是说,把1797*64
这个矩阵,变换成8*8
的不知道多少个的矩阵,arr.reshape(3,3)
把arr
变成一个3×3
的矩阵,行、列
T20190418:
1
2
3np.array[:]->全部元素。
np.array[1:]->从第一个到最后一个。
[[1,2,3],[1,2,3]] -> np.array[1:][0] = 1;1
X_flatten = X.reshape(X.shape[0], -1).T # X.T is the transpose of X.where each column represents a flattened image
train_set_x_flatten = train_set_x_orig.reshape(train_set_x_orig.shape[0],-1).T
与train_set_x_flatten = train_set_x_orig.reshape(train_set_x_orig.shape[1]*train_set_x_orig.shape[2]*train_set_x_orig.shape[3],-1)
的区别:
1 |
|
- 循环语句、条件
1
2
3
4if ... :
( ~ -> 非)
else:
for i in range(m):
1 | python 中 map 的构建: |
T20190425:
1 | PYTHON 中的" %S"%用法: |
1 | array: [1] * 2+[12,2]=[1,1,12,2] |
T20190426: 安装PyCharm, 配置Pycaffe
Python
解释器为C:\Development\Anaconda3\envs\py36\python3.6
Anaconda3
已经安装好了numpy matplot scipy
等库Pycaffe
接口的配置步骤:
参考happynear
中 readme
:[blog][https://github.com/happynear/caffe-windows/blob/ms/README.md]
必须是
python2.7
版本,因为third party libraries
是用python2.7
制作的,且_caffe.cpp
中的头文件也是python2.7
的格式。Miniconda
下载时可以勾选add to path
,将其加入环境变量中。然后使用prompt
下载python
的几个库。1
2conda install --yes numpy scipy matplotlib scikit-image pip
pip install protobuf修改
caffe
项目sln
中的CommonSettings.props
文件
1 | 1. <PythonSupport>true</PythonSupport> |
- 配置
pycaffe Property
1 | 1.include Directoies: 设为 |
- 编译
Pycaffe
文件 - Set
PythonPath
environment variable refer to<caffe_root>\Build\x64\Release\pycaffe
。
T20190427:
- 成功使用
Python+Pycharm
训练起了FCN
,数据集为onhand10K
的手势数据集。2分类问题。 - 参考了Blog(FCN训练不收敛的原因分析和最详细的FCN训练与测试自己的数据程序配置)
Pycaffe
写train.prototxt
,solve.prototxt
,deploy.prototxt
.Pycharm
中导入写Caffe
层(prototxt
层)是没有智能提示的,因为他是用python
外包的。直接调用即可。- 参考(
caffe Python API
整理):(参考博客[blog][https://www.jianshu.com/p/1a420445deea])
DATA层:
返回data和label可以在之后的层中作为输入。1
2
3
4
5data, label = L.Data( batch_size=batch_size,
backend=P.Data.LMDB, //数据库来源
source='mnist/mnist_test_lmdb',
transform_param=dict(scale=1./255),
ntop=2 #指定返回两个top blob )
卷积层:
1 | conv1 = L.Convolution( data_blob, |
这些都可以写成内部的函数然后就有智能提示啦啦啦,顺便还可以将一个conv+relu
合成一块。
1 | def conv(..,..,..) |
需要注意的是:前一个的输出名字得作为第二个的输入时的名字,名称要匹配。
全连接层:
1 | n.fc = L.InnerProduct(n.pool, |
损失层:
1 | net.loss = L.SofemaxWithLoss(net.fc7_1, net.label) |
一般论文创新点会有自己的定义的层,GitHub上会有该层的代码。FCN是一个python的数据读入层。
fine-tune 模型:
[FCN_github][https://github.com/shelhamer/fcn.berkeleyvision.org]
[参考了Blog][https://blog.csdn.net/jiongnima/article/details/78549326]
在
fine-tune
时初始值设为其他模型中的值,只需要将名称设为与下载模型中名称一样即可。
使用solver.net.copy_from(weights)
weights
是下载模型的路径。所以有些不需要初始化的层必须要修改其名字。并且注意层与层的输出维度的修改。(比如FCN是21类,而手只有2类)
数据格式:
FCN
的数据格式可以在caffe
训练时的error
猜测。不要忽略batch_size
。label
的类别是整数可以为0,1,2,3
。共4类。则一张img中只能出现0,1,2,3
四个值。不要小数。txt
,数据名称列表。- 获取可使用提供的
python
模板。get_txt
. - 这个
txt
产生一个train
的和一个test
的,里面的格式随solve.py
里面取出img时的字符串处理有关,在FCN
中作者是"{}/.../{}.jpg".format(self.*,index)
; 所以可以看出来txt
中只要前缀不要后缀jpg
,且train.prototxt
中data
的路径不用写完,那只是个总路径,路径中的...
可以分为train_image
文件夹 ,以及test_image
文件夹. 所以txt
文件需要存在train.prototxt
中dataset
的路径中。(图像的上一层路径)。不然会有路径错的问题
- 获取可使用提供的
1 | |train.txt |
solve.py
分为两个数据集:一个是VOC一个是SBDD,一个作为训练集,一个作为测试集。1
2in_ = in_[:,:,::-1],逆序。
in_ -= self.mean。减去均值。注意
几个prototxt的位置。数据集的位置,需要仔细。
详细的代码注释。
T20190428:
终于终于能训练自己的数据集了。FCN训练成功。
参考”FCN训练不收敛的原因分析和最详细的FCN训练与测试自己的数据程序配置”
论文
GitHub
上一般会提供作者自己new
的层,与一些py文件,这些文件都和训练有很大的关系。- FCN中提供了许多.py文件:
net.py
//用python生成ptototxt,注意:没有智能提示,可以封装写成内部函数来方便调用。其中返回值是层的名字(自定义)。- 注意的是当初始化设为别人的模型来finetune时名字相同的会赋值,所以要修改自己需要训练的层名字。
- 在
infer
时,net.load()
也是使用的这个方法,只不过基本所有的层都是重名的,然后赋值得到训练的模型数据,做一次forward(). infer
的deploy
去掉了最后的softmaxwithloss
,以及两个dropout层。在运行solver.py
时可以看到console
输出ignore
了这些层。
solver.py
//调用caffe训练的py.在这里要先load别人的训练好的模型来finetune- 设置gpu型号需要int强转。
- 在solver中不要caffe的自我test,而是采用了自定义的测试层。seg_tests()
- 需要有个train.txt存放数据的索引(名称)
voc_layers.py
//自定义py层,调用用L.Python
(模块名字,类型,输出参数个数,字典),返回值是top的两个- 这是数据层,所以没有
bckforward
。 '{}/{}.txt'.format
需要改路径。{}是上级目录,包含了train,test,
- 这是数据层,所以没有
vis.py
//后面可视化数据的工具 没有读懂score.py
//测试时调用surgery.py
//初始化数据my_solver.py
//是使用opencv版本的可视化数据。没有使用论文作者提供的vis.py
- 输入时是减去了均值的
- 数据长宽大小格式是
224x224
,label也是224x224
,只是通道数量不同 label
不是小数而是类。所以可视化mask是黑的,最大灰度值为1.
- FCN中提供了许多.py文件:
T20190501:学习style transfer 的源码记录
style transfer
是用PyCaffe
实现的
python 中主函数参数的parse:
1
2
3
4
5
61)import argparse 首先导入模块
2)parser = argparse.ArgumentParser() 创建一个解析对象
3)parser.add_argument() 向该对象中添加你要关注的命令行参数和选项
1.parser.add_argument("-s", "--style-img", type=str, required=True, help="input style (art) image")
-> name+类型。第二个双横线之后的名字 是用来获取的。args.style_img,这里——=_.
4)args = parser.parse_args() 进行解析,在args中得到数据caffe load_image(image_path)
->go to impletation
:1
2
3
4
5
6
7
8
9
10##源码
img = skimage.img_as_float(skimage.io.imread(filename, as_grey=not color)).astype(np.float32)
if img.ndim == 2:
img = img[:, :, np.newaxis]
if color:
img = np.tile(img, (1, 1, 3))
elif img.shape[2] == 4:
img = img[:, :, :3]
return img
###skimage.io.imread\cv2.imread
保存后的都是numpy
格式,但cv2的存储格式是BGR
,而skimage
的存储格式是RGB
1
2
3
4
5
6
7
8skimage.img_as_float(image).astype(np.float32)
img_as_float Convert an image to floating point format, with values in [0, 1]. Is similar to img_as_float64, but will not convert lower-precision floating point arrays to float64.
img_as_float32 Convert an image to single-precision (32-bit) floating point format, with values in [0, 1].
img_as_float64 Convert an image to double-precision (64-bit) floating point format, with values in [0, 1].
img_as_uint Convert an image to unsigned integer format, with values in [0, 65535].
img_as_int Convert an image to signed integer format, with values in [-32768, 32767].
img_as_ubyte Convert an image to unsigned byte format, with values in [0, 255].
img_as_bool Convert an image to boolean format, with values either True or False.astype(np.float32)
将数据转换为数组的数据float32
格式。一张彩色图片转换为灰度图后,它的类型就由unit8
变成了float-[0-1]
之间。slice
1
2
3对于np.array对象,可以使用数组的切片来分割数组。
1) a=array([1,2,3]) a[:2] ->只取前[0-2)项数据
2) 对于高维的,可以取高纬度的每一切片,img[:,:,:3],如果Img有4个通道+alpha,则只取其前三(H,W,C)img.ndim
返回数组的维度。rgb
是三维。1
2
3img = img[:, :, np.newaxis],如果是2维的则在第三位新建一维
如果还设为color图,那么将前一层的数据叠2层:
im =np.tile(img,(1,1,3))StyleTransfer
:1
2
3
4
5
61. for layer in self.net.blobs:
只返回键值,即conv1_1层的名字。
2.load_model:
1.transformer transformer.set_channel_swap("data", (2,1,0))#将 0,2维通道交换。
2.transformer.set_transpose("data", (2,0,1)) #改变维度的顺序,由原始图片(227,227,3)变为(3,227,227)
3.set_raw_scale: #大小0-255
T20190429:
python
中函数也是对象,可存入键值对中,也可以键值调用。1
2
3
4
5
6
7
8
9
10
11
12
13
14e.g:
def move_up(x)
x[1] += 1
def....
...
...
actions={
'up':move_up,
'down':move_down,
'left':move_left,
'right':move_right
}
for move in moves:
actions[move](coord)lamada
函数:
1.匿名函数,使用:lamada x:x[1],对输入变量输出x的第一维python
中高维度的argmax(axis=*)
out
=net.blobs['score'].data[0].argmax(axis=0)
该行可以很方便地寻找到每一个像素点所对应的最大概率类。
在C个H*W
层上遍历每一个点,看该点在哪个通道(预测的类)上的概率取最大值,并且返回的是该通道的下标。1
2
3
4array.argmax(axis)如果array是一维的话,只返回第一次出现的最大值的索引
axis : int, 可选,默认情况下,索引的是平铺的数组,否则沿指定的轴。可以按照每一个维度进行排序。但不是整个排序。
array.argsort() 对所有的数据进行排序,返回的Index,最小的在最前面。如果不加参数,则是默认使用最深的维度(shape的最后一个数所对应),的来排序
argsort(axis=0) 以第一维排序。看第一维有几层,那么返回的index最大是几。
简单的例子:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27#!/usr/bin/python
# -*- coding:utf8 -*-
import numpy as np
a = np.array([[[1,0,1,1],[6,4,3,4],[3,5,2,1]],[[4,2,2,0],[5,3,2,1],[3,1,0,7]]])
b= np.array([[1,1,1],[0,1,2]])
print(a)
#print(b)
#argmax(axis=1)
```
以第几维排序,然后返回的是第几维`index`,返回的是某维度的最大值的`index`
```python
#axis ==0 ->一维:将所有数据以第1维单独排列,每一个取最大。
#a=[2x3x4]
print(a.argmax(axis=0)) #返回的是降axis=0维的长度(axis=1 x axis=2)[3x4],而值为axis=0维的个数。此处行维2个[0,1]
print(a.argmax(axis=2)) #返回的是降axis=2维的长度(axis=0 x axis=1)[2x3],而值为axis=2维的个数。此处行维4个[0-3]
print ('eg2:')
a='python'
b=a[::-1] #间距为1,倒序
print (b)
c=a[::-2] #间距为2
print (c)
a = [0,1,2,3,4,5,6,7,8,9]
b = a[1:3] # [1,2]
#a[i,j,x] 取a的i到j[i,j),步长为x #Out[13]: [1, 2]
c=a[1:5] #Out[15]: [1, 2, 3, 4]
d=a[1:5:1] #Out[17]: [1, 2, 3, 4]
e=a[1:5:2] #Out[19]: [1, 3]
map{}
:map{}
是Python
内置的高阶函数,它接收一个函数 f 和一个 list,并通过把函数 f 依次作用在 list 的每个元素上,得到一个新的 list 并返回。1
2
3
4
5
6
7
8
9def f(x):
return x*x
print map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])//map()函数不改变原有的 list,而是返回一个新的 list。
```
```python
l=map(int,'1234')
for i in l:
print(type(i))
print(i)format()
字符串格式化。1
2str = 'a is b and {} is {} not {}'.format('aa','bb',1)
str = 'a is b and {0} is {2} not {1}'.format('aa','bb',1)//可改变其顺序
1 | 1.对齐补齐: |
T20190501:
python 中的 类:
1 | class className: |
T20190510:
squeeze()
1 | caffe.io.load_image('').squeeze() 读入图像是0-1之间,squeeze()是去掉 维度数量为1 的维度 |
np.newaxis
1 | im[np.newaxis,np.newaxis,:,:]是在im的原来基础上新了两个层,然后将源数据放在其::对应上 |
分别打印一下s
与list
,输出是这样的:(0, 1, 2, 3, 7.5)
((0, 1, 2, 3, 7.5),)
可以看出当函数中参数位置上有号时,其的作用时不确定输入参数
的大小:传入的变量会被收集为tuple
对于键值map
则需要**
来解包。
1 | data[...]它是省略所有的冒号来用省略号代替,当无法显示知道data的维度信息的时候 |
T20190519:
net
1 | 1. net.blobs['data'].reshape(*im_input.shape) 将data层reshape到输入图像的大小,这里时灰度图像。 |
np.array
1 | 1. array[0,1] = array[0][1],array[1,:2], ->第一维的第一到二维的元素。 |
forward()
在pycaffe
中不同于c++ caffe
,其 forward()
返回值是一个字典类型其对应键值才是blob,output[‘prob’][0],而c++中直接返回blob,net_->output_blobs()[0];
slice()
1 | b = a[i:j:s]这种格式呢,i,j与上面的一样,但s表示步进,缺省为1. |
所以在Python
中转换图像的通道顺序就很方便了,直接img_trans = img[::-1]
.
在 caffe
中 CHW
来存放,所以第一维是C,因为img[0] 是 Red channel;img[1] 是 Green channel
倒序只是第一维导。注意的是python中图像的类型转换uint8
:array.astype(np.uint8),Python默认的数字的数据类型为双精度浮点数
1
2for layer_name, blob in net.blobs.iteritems():
# 这样的foreach是对于键值map的,有两个输出一个是键一个是值。1
plt.imshow(img,cmap='gray',vmin=.vmax=) cmap 是显示类型,vmin,vmax 是归一化
pad()
1 | padding = (((0, n ** 2 - data.shape[0]), |
imshow()
的array
其channel
是放在最后的
transpose
transpose
会将调换通道序 注意非原地操作!!!
注意原地操作和非原地:dif.transpose(1,0,2)
是非原地的。
需要赋值才行。dif = dif.transpose.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28data = data.reshape((4,4,8,8))
print( 'data='+ str(data[1,2,3,4]))
print('data_transpose='+str(data.transpose(0,2,1,3)[1,3,2,4]))
使用转置时,相近的','可以相乘起来,然后reshape 到一个更低维的张量。
不用在意transpose 后的细节,着重点应该放在维度本身的意义上。【数据转维、多维度一图可视化】
1.如:将solver.net['conv1'][0].data ->在样例中其是(20,1,5,5)的数据,要想将其转换在一张图片上进行Imshow
->先去前8通道。:
data = solver.net['conv1'][0].data[:8].squeeze() #其shape 为(8,5,5)
或者data = solver.net['conv1'][0].data[:8,0]
->padding = ((0,0),(0,1),(0,1))
data = np.pad(data,padding,mode='constant',constant_value = max(data))->注意constant_value的取值,需要是该data的最大值,
如果是很大的值,那么在之后imshow时,会全黑,应为默认的imshow是会归一化的。
->此时data.shape=(8,6,6)
->想画的图:一行八副图。->data = data.transpose(1,0,2)将第二维与第一维交换数据,第二维是行,所以交换后为:
(6,8,6)->第一维是行,有6个通道,每个通道有8副图的6个列通道。
->reshape(6,48):6个像素行,每一行有48个像素。
# solver.step(1)
# dif = solver.net.params['conv1'][0].diff[:, 0][:]
# maxx = np.max(dif)
# dif = np.pad(dif, ((0, 0), (0, 1), (0, 1)), mode='constant', constant_values=maxx if maxx!=0 else 1 )
# print 'maxx: '+str(maxx)
# print 'dif1: '+str(dif.shape)
# dif = dif.reshape(4,5,6,6)
# dif = dif.transpose(0,2,1,3)
# print 'dif2: '+str(dif.shape)
# plt.subplot(2, 1, 1)
# imshow(dif.reshape(24,30),cmap='gray');
caffe的一次训练流程:【caffe注意实项】
1 | 1. 使用SGDSolver直接load caffe网络。 |
1
2
3net.params['name'][0](->w;[1]->bias;).data->data;diff->gradient
solver.net.blobs['label'].data ->标记
solver.test_net[0].blobs['label'].data
python 多图subplot:
1 | plt.subplot(2, 1, 1) |
python 中获得图像句柄:
1 | figure(figsize=(10, 2)) |
python 中三目运算符:
1 | a = x if x>0 else y #当x大于0时返回x,否则返回y |
python /
与 //
在3.0
中" / "
就表示 浮点数除法,返回浮点结果;" // "
表示整数除法。2.0
中/
要看数据类型。或在最开始from __future__ import division
1
2
3
4
5
6
7
8
9
10
11
12
13
14测试solver.net_test[0].blobs['label'].data
solver.net_test[0].forward()->初始化测试的数据,batch_size大小。由测试网络定义。
solver.net_test[0].forward(start='name') ->从**层开始可以不用load数据。
##
solver.test_nets[0].forward() #第1次 / 第101次 == 1次
for test_it in range(100): #读100次 /
solver.test_nets[0].forward()
print solver.test_nets[0].blobs['label'].data[:8]
solver.test_nets[0].forward(start='conv1')
print solver.test_nets[0].blobs['label'].data[:8]
output[it] = solver.test_nets[0].blobs['score'].data[:8]
##
如果从lmdb中读入数据读完一轮,那么将会循环。
这也时为什么在样例中可以一直读到不同轮次的output.
np.array中支持array的每个item单独比较,
1
2
3
4
5
6
7
8
9
10[2,1,3,1] == [2,0,0,1] ->[t,f,f,t]
如果两个array不同大小,则是返回F
a = np.array([[2,3],[1,2]])
b = np.array([[0,3],[2,1]])
print (a==b) ---> [[False True],[False False]]
False = 0,True = 0;
..range = np.arange
np.array中支持对整个list中所有数单独做运算:
2*np.array([1,2,3]) -->[2,4,6]一张图中画两个函数:
1
2
3
4
5
6
7
8
9#fig, ax1 = plt.subplots()
_, ax1 = subplots()
ax2 = ax1.twinx() #公用x轴,ax1.twiny()公用y轴
ax1.plot(arange(niter), train_loss) #x,y
ax2.plot(test_interval * arange(len(test_acc)), test_acc, 'r') #x,y
#在test_acc 中本来是每step(1),25次后记录对10000的正确率。所以实际上对应的迭代次数是
25 50 75....250 次迭代所测试的结果。
整个x粒度为1,0-250,第一个图像画loss,train_loss[it]记录了每次迭代的Loss
但在test_acc[it]中记录的是25,50...的测试结果,所以需要×25的x粒度。python 中imshow的补足:
Imshow会将图像中的数据归一化显示出来,默认是minmax。imshow将数据标准化为最小和最大值。 您可以使用vmin和vmax参数或norm参数来控制(如果您想要非线性缩放)。 如果imshow的不是连续的图像,维度长度太小其中会有过渡线性的填充不足, 如果不想要线性渐变的填充的话可以使用interpolation='nearest',最近邻填充。
写solver.prototxt
需要:from caffe.proto import caffe_pb2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41train_net_path = 'mnist/custom_auto_train.prototxt'
test_net_path = 'mnist/custom_auto_test.prototxt'
solver_config_path = 'mnist/custom_auto_solver.prototxt'
from caffe.proto import caffe_pb2
s = caffe_pb2.SolverParameter()
# Set a seed for reproducible experiments:
# this controls for randomization in training.
s.random_seed = 0xCAFFE
# Specify locations of the train and (maybe) test networks.
s.train_net = train_net_path
s.test_net.append(test_net_path)
s.test_interval = 500 # Test after every 500 training iterations.
s.test_iter.append(100) # Test on 100 batches each time we test.
s.max_iter = 10000 # no. of times to update the net (training iterations)
# EDIT HERE to try different solvers
# solver types include "SGD", "Adam", and "Nesterov" among others.
s.type = "SGD"
# Set the initial learning rate for SGD.
s.base_lr = 0.01 # EDIT HERE to try different learning rates
# Set momentum to accelerate learning by
# taking weighted average of current and previous updates.
s.momentum = 0.9
# Set weight decay to regularize and prevent overfitting
s.weight_decay = 5e-4
# Set `lr_policy` to define how the learning rate changes during training.
# This is the same policy as our default LeNet.
s.lr_policy = 'inv'
s.gamma = 0.0001
s.power = 0.75
# EDIT HERE to try the fixed rate (and compare with adaptive solvers)
# `fixed` is the simplest policy that keeps the learning rate constant.
# s.lr_policy = 'fixed'
# Display the current training loss and accuracy every 1000 iterations.
s.display = 1000
# Snapshots are files used to store networks we've trained.
# We'll snapshot every 5K iterations -- twice during training.
s.snapshot = 5000
s.snapshot_prefix = 'mnist/custom_net'
# Train on the GPU
s.solver_mode = caffe_pb2.SolverParameter.GPU
# Write the solver to a temporary file and return its filename.
1 | image[image < 0], image[image > 255] = 0, 255 |
python 中文件是否存在
1 | python 中文件是否存在:assert os.path.exists(path_file) |
load the txt in python
1 | Python默认的数字的数据类型为双精度浮点数 |
‘string’.join()
1 | _str.join(src)用于以特定的分隔符(_str)分隔源变量(src),将其作为新的元素加入到一个列表中 |
临时文件的创建:
1 | empfile.NamedTemporaryFile(delete=False) |
caffe
中 DummyData
层是用来产生数的,就像np.random
一样产生一些随机数。
程序解析:
1 | def run_solvers(niter, solvers, disp_interval=10): |
该函数功能是对两个已经定义的solver
进行细节处理:
solvers
有两个网络,是在caffe/02-fine-tuning
中的例子。其中一个是没有初始化赋值的model
,一个是初始化了的model.
1
2
3
4
5
6
7
8
9
10
11style_solver_filename = solver(style_net(train=True))
style_solver = caffe.get_solver(style_solver_filename)
style_solver.net.copy_from(weights)
# For reference, we also create a solver that isn't initialized from
# the pretrained ImageNet weights.
scratch_style_solver_filename = solver(style_net(train=True))
scratch_style_solver = caffe.get_solver(scratch_style_solver_filename)
style_solver是初始化了的:style_solver.net.copy_from(weights)
在caffe中也可以使用caffe.Net("prototxt",weights)来初始化。
也可以用style_solver.net.copy_from(weights),weights caffemodel的路径
3.1
2blobs = ('loss', 'acc') #将要取出的模型的blob的名字。
#格式为:s.net.blobs['loss'].data[0] ->
4.1
2
3
4loss, acc = ({name: np.zeros(niter) for name, _ in solvers}
for _ in blobs)
list_a, list_b = ({} for _ in blobs),可以生成两个list。