现在可以开始 ”AdaIN 风格转变“了。
先把三个模型用Opencv转换成文本格式,decoder.t7 和 decoder-content-similar.t7 成功了
.而 vgg_normalised.t7 转化不了,哪个 vgg_normalised.caffemodel 又下不下。
模型下载地址:
https://s3.amazonaws.com/xunhuang-public/adain/decoder.t7
https://s3.amazonaws.com/xunhuang-public/adain/decoder-content-similar.t7
https://s3.amazonaws.com/xunhuang-public/adain/vgg_normalised.t7
用 VGG_ILSVRC_19_layers.caffemodel 应该是不行的,因为decoder.t7 是针对vgg_normalised.t7 训练的,除非自己训练。
先看一下AdaIN-style 转换流程图:
从上图可以看出 编码器中并没有用到特别的层,为什么不能转换呢?
用十六进制编辑器打开 vgg_normalised.t7 文件 并
结合 Opencv3.3 和4.0的torch_importer.cpp 以及 Python 读取 Torch 的 torchfile.py 可以知道,
vgg_normalised.t7 文件中第一个层中引用了一个外部文件函数
@./helpers/preprocess.lua
OpenCV对这种情况是不处理的就退出了。
有什么办法跳过这个层取出后面的参数数据呢?
t7 模型的存放用了递归,整个文件是一个对象,然后对象之中有对象,表中有表,表中有对象,绕来绕去,总之非常复杂。
按它的流程 就是在人家的脚后跟,不能错一点,人家稍稍改了,就会出错。,
如果,按层为单位搜索,就会非常简单,遇到未知的可以跳过,不会影响其它层。
流程 :
1。搜索层,取出层名,取出参数
2。如果是未知层名,不取参数,搜索下一层
3。循环,直至结束
是不是很简单。
先找一下每层名字,就是
"V 1" 或 "V 2" 或 "V 3" + "nn."
前面的V是版本号 ,后面的 nn. 就是层名
void readModel(string name)
{
// 确保所获得的文件指针合法
if(fopen_s(&m_FilePointer,name.data(), "rb")!=0)
{
char Message[255] = {0};
sprintf_s(Message, "没有找到这个文件: %s!", name.data());
cout<<Message<<endl;
return ;
}
ofstream fout ("Torch模型中的层名.txt");
int V1num=0;
while(1){
if(跳到V位置())//找一个版本 "V 1" "V 2" "V 3"
;
else
break;
long fpos = ftell(m_FilePointer);//当前文件位置。
//读出类名
string TorchClassName = readString();
if(startsWith(TorchClassName,"nn.")) //"nn." 开头的是层名
{
V1num++;
//显示层名
cout<<TorchClassName<<endl;
//保存到文件
//fout<<"----"<<V1num<<"----"<<endl;
fout<<TorchClassName<<endl;
}
}
fout.close ();
fclose(m_FilePointer); // 关闭当前的文件指针
system("pause");
}
打开文件可以看到vgg_normalised.t7 中的各层名了:
nn.Sequential
nn.SpatialConvolution ------------------预处理卷积 3维->3维
nn.SpatialReflectionPadding
nn.SpatialConvolution --------------Conv1_1---卷积 3维->64维
nn.ReLU
nn.SpatialReflectionPadding
nn.SpatialConvolution --------------Conv1_2---卷积 64维不变
nn.ReLU
nn.SpatialMaxPooling ---------------pool1---2倍缩小
nn.SpatialReflectionPadding
nn.SpatialConvolution --------------Conv2_1---卷积 64维->128维
nn.ReLU
nn.SpatialReflectionPadding
nn.SpatialConvolution --------------Conv2_2---卷积 128维不变
nn.ReLU
nn.SpatialMaxPooling ---------------pool2---2倍缩小
nn.SpatialReflectionPadding
nn.SpatialConvolution --------------Conv3_1---卷积 128维->256维
nn.ReLU
nn.SpatialReflectionPadding
nn.SpatialConvolution ---------------Conv3_2---卷积 256维不变
nn.ReLU
nn.SpatialReflectionPadding
nn.SpatialConvolution ---------------Conv3_3---卷积 256维不变
nn.ReLU
nn.SpatialReflectionPadding
nn.SpatialConvolution ---------------Conv3_4---卷积 256维不变
nn.ReLU
nn.SpatialMaxPooling ----------------pool3---2倍缩小
nn.SpatialReflectionPadding
nn.SpatialConvolution ----------------Conv4_1---卷积 256维->512维
nn.ReLU ------------------------------relu4-1--->输出
nn.SpatialReflectionPadding
nn.SpatialConvolution
nn.ReLU
nn.SpatialReflectionPadding
nn.SpatialConvolution
nn.ReLU
nn.SpatialReflectionPadding
nn.SpatialConvolution
nn.ReLU
nn.SpatialMaxPooling ------------------2倍缩小
nn.SpatialReflectionPadding
nn.SpatialConvolution
nn.ReLU
nn.SpatialReflectionPadding
nn.SpatialConvolution
nn.ReLU
nn.SpatialReflectionPadding
nn.SpatialConvolution
nn.ReLU
nn.SpatialReflectionPadding
nn.SpatialConvolution
nn.ReLU
虚线是我后来加上去的,第一层预处理卷积是VGG19中没有的。
先这样吧。