好久沒寫博客了,險些以為自己找不到密碼了。
最近抽空參與了個小項目,很慚愧,只做了三件小事
1. 基於PyTorch訓練了一系列單圖像超分辨神經網絡
基於PyTorch訓練了一系列單圖像超分辨神經網絡,超分辨系數從2-10。
該部分的實現參考了pytorch官方repo中的SR例程,訓練程序包含於`./train`文件夾。該項目
基於高效子像素卷積層[1]進行空間分辨率提升操作,訓練速度極快。
[1] ["Shi W, Caballero J, Huszar F, et al. Real-Time Single Image and
Video Super-Resolution Using an Efficient Sub-Pixel Convolutional
Neural Network[J]. 2016:1874-1883.](https://arxiv.org/abs/1609.05158)
2. 把訓練好的模型權值轉存為MATLAB文件。
簡單粗暴,異常直接,只要把對應卷積層的權值全部提取出來就可以了。
提取的時候注意一點,要把pytorch中的Variable格式轉換為Tensor,再轉換為CPU模式,最終轉換為numpy數組。
這一系列過程合並起來就是:
Var.data.cpu().numpy()
具體實現如下:
1 from __future__ import print_function 2 3 import torch 4 import numpy as np 5 import scipy.io as sio 6 7 for i in [2, 3, 4, 5, 6, 7, 8, 9, 10]: 8 9 model_name = 'model_upscale_{}_epoch_101.pth'.format(i) 10 model = torch.load(model_name) 11 print(model._modules) 12 13 weight = dict() 14 weight['conv1_w'] = model._modules['conv1']._parameters['weight'].data.cpu().numpy() 15 weight['conv2_w'] = model._modules['conv2']._parameters['weight'].data.cpu().numpy() 16 weight['conv3_w'] = model._modules['conv3']._parameters['weight'].data.cpu().numpy() 17 weight['conv4_w'] = model._modules['conv4']._parameters['weight'].data.cpu().numpy() 18 19 weight['conv1_b'] = model._modules['conv1']._parameters['bias'].data.cpu().numpy() 20 weight['conv2_b'] = model._modules['conv2']._parameters['bias'].data.cpu().numpy() 21 weight['conv3_b'] = model._modules['conv3']._parameters['bias'].data.cpu().numpy() 22 weight['conv4_b'] = model._modules['conv4']._parameters['bias'].data.cpu().numpy() 23 24 sio.savemat('model_upscale_{}.mat'.format(i), mdict=weight)
3. 把網絡的test過程移植到了MATLAB平台,並撰寫了測試代碼。
把卷積層和pixelshuffle層用matlab重寫了一下。
復現pixelshuffle層的時候遇到了一些麻煩,又回頭看了下pytorch里的測試代碼
`https://github.com/pytorch/pytorch/blob/master/test/test_nn.py `
# https://github.com/pytorch/pytorch/blob/master/test/test_nn.py def _verify_pixel_shuffle(self, input, output, upscale_factor): for c in range(output.size(1)): for h in range(output.size(2)): for w in range(output.size(3)): height_idx = h // upscale_factor weight_idx = w // upscale_factor channel_idx = (upscale_factor * (h % upscale_factor)) + (w % upscale_factor) + \ (c * upscale_factor ** 2) self.assertEqual(output[:, c, h, w], input[:, channel_idx, height_idx, weight_idx])
理了理思路,改寫成MATLAB代碼:
1 function [ outputs ] = PixelShuffle( inputs, upscale_factor ) 2 % PixelShuffle : 3 % 4 % input : N, upscale_factor ** 2, H, W 5 % output : N, 1, H*upscale_factor, W*upscale_factor 6 7 [N, ~, H, W] = size(inputs); 8 H_out = H*upscale_factor; 9 W_out = W*upscale_factor; 10 outputs = zeros([N, 1, H_out, W_out]); 11 for i = 1:N 12 for h = 1: H_out 13 for w = 1:W_out 14 height_idx = floor(h / upscale_factor+0.5); 15 weight_idx = floor(w / upscale_factor+0.5); 16 channel_idx = (upscale_factor * mod(h-1, upscale_factor)) + mod(w-1, upscale_factor)+1; 17 outputs(i, 1, h, w) = inputs(i, channel_idx, height_idx, weight_idx); 18 end 19 end 20 end 21 end
4. 完整工程github鏈接。
https://github.com/JiJingYu/super-resolution-by-subpixel-convolution
模型權值已保存為matlab權值,直接在matlab中運行`demo.m`文件即可驗證