獲取文件夾下所有文件:
def get_all(cwd, result):
get_dir = os.listdir(cwd)
for i in get_dir:
sub_dir = os.path.join(cwd,i)
if os.path.isdir(sub_dir):
get_all(sub_dir, result)
else:
result.append(cwd+"\\"+i)
return result
保存數據爲二進制:
data = []
for name, param in net.named_parameters():
print("name:", name, " param:", param.size())
pa = param.reshape(-1).to(device_cpu)
numpy_param = pa.detach().numpy()
print("param:", len(numpy_param))
data += list(numpy_param)
print("len data:", len(data))
f = open('net.bin','wb+')
data_struct = struct.pack(('%df' % len(data)), *data)
f.write(data_struct)
f.close()
list 數據寫入文件 注:line結尾加 "\n"
def write_line(file_name, lines):
if file_name == "":
return
with open(file_name, "a+") as fs:
for line in lines:
fs.writelines(line)
fs.close()
讀取數據到list
def read_file(data_file, mode='more'):
try:
with open(data_file, 'r') as f:
if mode == 'one':
output = f.read()
return output
elif mode == 'more':
output = f.readlines()
# return map(str.strip, output)
return output
else:
return list()
except IOError:
return list()
rect 縮放:
def get_zoom_rect(rect, width, height, zoom):
x, y = rect[0], rect[1]
w = rect[2] - rect[0]
h = rect[3] - rect[1]
w1 = min(w*zoom, width-x)
h1 = min(h*zoom, height-y)
x1 = min(max(x - (w1 - w)/2, 0), width-w1)
y1 = min(max(y - (h1 - h)/2, 0), height-h1)
#print("rect:", rect, " new:", [x1, y1, x1+w1, y1+h1])
return [x1, y1, x1+w1, y1+h1]
fuse BatchNorm 網絡
import torch
import torch.nn as nn
import torchvision as tv
class DummyModule(nn.Module):
def __init__(self):
super(DummyModule, self).__init__()
def forward(self, x):
# print("Dummy, Dummy.")
return x
def fuse(conv, bn):
w = conv.weight
mean = bn.running_mean
var_sqrt = torch.sqrt(bn.running_var + bn.eps)
beta = bn.weight
gamma = bn.bias
if conv.bias is not None:
b = conv.bias
else:
b = mean.new_zeros(mean.shape)
w = w * (beta / var_sqrt).reshape([conv.out_channels, 1, 1, 1])
b = (b - mean)/var_sqrt * beta + gamma
fused_conv = nn.Conv2d(conv.in_channels,
conv.out_channels,
conv.kernel_size,
conv.stride,
conv.padding,
bias=True)
fused_conv.weight = nn.Parameter(w)
fused_conv.bias = nn.Parameter(b)
return fused_conv
def fuse_module(m):
children = list(m.named_children())
c = None
cn = None
for name, child in children:
if isinstance(child, nn.BatchNorm2d):
bc = fuse(c, child)
m._modules[cn] = bc
m._modules[name] = DummyModule()
c = None
elif isinstance(child, nn.Conv2d):
c = child
cn = name
else:
fuse_module(child)
def test_net(m, input):
import time
s = time.time()
o_output = m(input)
print("Original time: ", time.time() - s)
fuse_module(m)
s = time.time()
f_output = m(input)
print("Fused time: ", time.time() - s)
print("Max abs diff: ", (o_output - f_output).abs().max().item())
assert(o_output.argmax() == f_output.argmax())
# print(o_output[0][0].item(), f_output[0][0].item())
print("MSE diff: ", nn.MSELoss()(o_output, f_output).item())
使用方法:
use_cuda = True
device_cpu = torch.device('cpu')
net = FCNETCTC(len(CHARS)).to(device_cpu)
net.load_state_dict(torch.load("weights/best_net_ctc_params_opt1.pkl", map_location=device_cpu))
net.eval()
example = torch.rand(1, 3, 24, 94)
test_net(net, example)
均值歸一化:
img_tensor = img_tensor.permute({0, 3, 1, 2}); //翻轉讓通道是第二個維度
//均值歸一化
img_tensor[0][0] = img_tensor[0][0].sub_(0.485).div_(0.229);
img_tensor[0][1] = img_tensor[0][1].sub_(0.456).div_(0.224);
img_tensor[0][2] = img_tensor[0][2].sub_(0.406).div_(0.225);