diff --git a/styleTransfer_projectReport.txt b/styleTransfer_projectReport.txt new file mode 100644 index 0000000..5534105 --- /dev/null +++ b/styleTransfer_projectReport.txt @@ -0,0 +1,303 @@ +�����������������������������Ǩ����Ŀ���� + 10205101496 ������ + + +ժҪ�� + �����������ͼ����������ȡ��������������Ľ�ϲ����Ǽ�������Ĵ��£������������������������Ա�ĸ߶ȹ�ע���ʶ���Щ���һ���pytorch�Է��Ǩ�ƽ�����һ���̶ȵ�ѧϰ������ھ���������ʵ��ͼ����Ǩ�ƣ�Style Transfer����ͨ���Կγ����ĵ��Ķ�����CSDN�ϲ鿴һЩ��صIJ��ͣ��Լ�д��һ������ʵ���˷��Ǩ�ƹ��ܡ� + + +���ģ� + +1 �˽���Ǩ�� + +��ʵͼ����Ǩ���㷨��ʵ���߼��������ӣ�����ѡȡһ��ͼ����Ϊ��׼ͼ������ͼ�񣩣�Ȼ��ѡȡ��һ�����߶ั��Ϊ����ϣ����ȡ��Ӧ����ͼ�񣨷��ͼ�񣩣����ڱ�֤����ͼ������������Ե�ǰ���£������ͼ��ķ����������ͼ���С� + +ͼ����Ǩ��ʵ�ֵ��ѵ���������Ч��ȡһ��ͼ��ķ������ͨ������������ľ������ȡͼ�����Ҫ������Ȼ�������ȡ�������� + +��ʵ��ͼ����Ǩ�Ƴɹ������ڲ�ͬ���˶������б�׼Ҳ���ںܴ�IJ��죬��������ѧ��Ҳ��û�ж��������������ͼ����Ǩ�������ϸ�Ķ��塣ͼ��ķ������˷ḻ�����ݣ�����ͼ�����ɫ��ͼ���������ͼ���������ͼ������Ҫ��������ں��壬�ȵȡ�������ͨ�����Ǿ�������ͼ����ijЩ�����Ͽ����������ƣ��ͻ���Ϊ��������ͬһ�������ϵ�����Ƕ���רҵ��ʿ���ԣ����Ǹ���עͼ�����εľ����Ƿ���ͬ������ͼ�����Ƿ������Ǩ��Ҳ��ÿ���˵���֪��أ�������ʵ���и�ע��ͼ�����Ӿ���չ�����Ƿ�����˷��Ǩ�ơ� + +����20���ͳ����кܶ�ѧ�߿�ʼ�о�ͼ����Ǩ���ˣ���ʱ������ͨ����ȡ���ͼ���������ɫ���߽�֮�����������ɷ��Ǩ�ƣ����߼�һЩ�ǽ����ѧ�и���ͼ��任��ͳ�Ʒ�������ɷ��Ǩ�ƣ���������Ч���������롣ֱ��2015���Ժ��ܵ�����������ڼ�����Ӿ������������ֵ����������ǽ���������������ǿ���ͼ��������ȡ���ܣ���ͼ����Ǩ�Ƶ�����õ��˿��Ƹ��õĽ���� + + +2 PyTorchͼ����Ǩ��ʵս + +ʵ�ֲ��裺 + + �����ȣ�����Ҫ��ȡһ������ͼƬ��һ�ŷ��ͼƬ�� + ��Ȼ������������ֵ�����ݶ���ֵ������ͼƬ֮�����ݲ���̶ȣ��ͷ�����ֵ������ͼƬ֮��ķ�����̶ȣ��� + ����󣬽���������ģ�ͣ�������ͼƬ�е����ݺͷ��ͼƬ�ķ�������ȡ��������ͼƬΪ��׼�������뽨����ģ���У������ϵ������ݶ���ֵ�ͷ�����ֵ����������������С��������ͼƬ�������������ںϵ�ͼƬ + +�ȵ�����صİ��� + + import torch + from torch.autograd import Variable + import torchvision + from torchvision import transforms, models + import copy + from PIL import Image + import matplotlib.pyplot as plt + +���Ŷ�ȡ����ͼƬ������ͼƬ�ͷ��ͼƬ����ͼƬչʾ���£� + + +loadimg()����������Ǵ��ͼƬ��·�����������£� +#--------------------------1.����Ԥ�������������� +transform = transforms.Compose([transforms.Resize([224,224]), + transforms.ToTensor()]) + +def loadimg(path = None): + img = Image.open(path) + img = transform(img) + img = img.unsqueeze(0) + return img + +content_img = loadimg('images/1.jpg') #������Լ����ͼƬ��λ�� +content_img = Variable(content_img).cuda() +style_img = loadimg('images/2.jpg') +style_img = Variable(style_img).cuda() + +2.1 ͼ���������ʧ +���ݶ���ֵ����ʹ�þ��������Ϊ��ʧ�������ڴ����ж����ͼ��������ʧ���£� +class Content_loss(torch.nn.Module): + def __init__(self,weight,target): + super(Content_loss,self).__init__() + self.weight = weight + self.target = target.detach()*weight + self.loss_fn = torch.nn.MSELoss() + + def forward(self,in_put): + self.loss = self.loss_fn(in_put*self.weight,self.target) + return in_put + + def backward(self): + self.loss.backward(retain_graph = True) + return self.loss + + +���ϴ����еIJ����� + + target��ͨ��������ȡ��������ͼ���е����ݣ� + weight���������õ�һ��Ȩ�ز����������������ݺͷ������ϳ�ͼ���Ӱ��̶ȣ� + in_put��������ͼ�� + target.detach()���ڶ���ȡ�������ݽ�������������Ҫ�����ݶȣ� + forward�������ڼ�������ͼ�������ͼ��֮�����ʧֵ�� + backward�������ݼ���õ�����ʧֵ���к��򴫲�����������ʧֵ + + +2.2 ͼ��ķ����ʧ +������ͬ��ʹ�þ��������Ϊ��ʧ�������������£� +class Style_loss(torch.nn.Module): + def __init__(self,weight,target): + super(Style_loss,self).__init__() + self.weight = weight + self.target = target.detach()*weight + self.loss_fn = torch.nn.MSELoss() + self.gram = Gram_matrix() + + def forward(self,in_put): + self.Gram = self.gram(in_put.clone()) + self.Gram.mul_(self.weight) + self.loss = self.loss_fn(self.Gram,self.target) + return in_put + + def backward(self): + self.loss.backward(retain_graph = True) + return self.loss + +�����ʧ����Ĵ��������������ʧ����Ĵ������ƣ���֮ͬ�����ڴ�����������Gram_matrix�ඨ���ʵ�������˷����ʧ�ļ��㡣����ʵ�ֵ��Ǹ���ķ����Gram matrix���Ĺ��ܡ�����ͨ��������������ȡ�˷��ͼƬ�ķ����Щ�����ʵ����������ɵģ����ֵĴ�С������ͼƬ�з���ͻ���̶ȣ���Gram�����Ǿ�����ڻ����㣬������������뵽�þ��������ͼ�д�����ֻ��ø�������൱��ͼƬ�ķ�񱻷Ŵ��ˣ��Ŵ�ķ���ٲ�����ʧ���㣬���ܹ������ĺϳ�ͼƬ���������Ӱ�졣�����Ĵ������£� + +class Gram_matrix(torch.nn.Module): + def forward(self,in_put): + a,b,c,d = in_put.size() + feature = in_put.view(a*b,c*d) + gram = torch.mm(feature,feature.t()) + return gram.div(a*b*c*d) + + +2.3 ģ�ʹ�Ͳ����Ż� +�����������ʧ�ͷ����ʧ֮�����ǻ���Ҫ�һ���Զ���ģ�ͣ�����ʹ��VGG16ģ�ͣ�������������������ģ���С���������Ҫ������Ǩ��һ�������������������ȡ���֣�������ز��֣����������£� + +cnn = models.vgg16(pretrained = True).features #Ǩ��VGG16�ܹ���������ȡ���� +# if use_gpu: +# cnn = cnn.cuda() +#ָ���������������зֱ�����һ����ȡ���ݺͷ�� +content_layer = ["Conv_3"] +style_layer = ["Conv_1","Conv_2","Conv_3","Conv_4"] +#���屣��������ʧ�ͷ����ʧ���б� +content_losses = [] +style_losses = [] +#ָ��������ʧ�ͷ����ʧ�����õ����ں�ͼƬ��Ӱ��Ȩ�� +content_weight = 1 +style_weight = 1000 + + +����������ͷϷ���ͼ����Ǩ��ģ�ͣ��������£� + +new_model = torch.nn.Sequential() #�����յ�ģ�� +model = copy.deepcopy(cnn) +#deepcopy��ƣ��������ƶ�����ȫ�ٸ���һ����Ϊ�������¸��嵥�����ڣ��ı�ԭ�б����ƶ��󲻻���Ѿ����Ƴ������¶������Ӱ�졣 +#copydz���ƣ����������һ�������Ķ��󵥶����ڣ���ֻ�ǽ�ԭ�е����ݿ����һ���±�ǩ +#���Ե�����һ����ǩ���ı��ʱ�����ݿ�ͻᷢ���仯����һ����ǩҲ����֮�ı䡣 +gram = Gram_matrix() + +use_gpu = torch.cuda.is_available() +if use_gpu: + model = model.cuda() + new_model = new_model.cuda() + gram = gram.cuda() + + +index = 1 +#ֻʹ��Ǩ��ģ��������ȡ���ֵ�ǰ8�� +for layer in list(model)[:8]: + if isinstance(layer,torch.nn.Conv2d): + name = "Conv_" + str(index) + #ʹ��add_module������յ�ģ�ͼ���ָ���IJ��ģ�� + new_model.add_module(name,layer) + if name in content_layer: + target = new_model(content_img).clone() + content_loss = Content_loss(content_weight,target) + new_model.add_module("content_loss_"+str(index),content_loss) + content_losses.append(content_loss) + + if name in style_layer: + target = new_model(style_img).clone() + target = gram(target) + style_loss = Style_loss(style_weight,target) + new_model.add_module("style_loss_"+str(index),style_loss) + style_losses.append(style_loss) + + if isinstance(layer,torch.nn.ReLU): + name = "ReLU_"+str(index) + new_model.add_module(name,layer) + index = index + 1 + + if isinstance(layer,torch.nn.MaxPool2d): + name = "MaxPool_"+str(index) + new_model.add_module(name,layer) + +���ϴ����У�for layer in list(model)[:8]ָ�������ǽ����õ�Ǩ��ģ��������ȡ���ֵ�ǰ8�㣬��Ϊ���ǵ�������ȡ�ͷ����ȡ��ǰ8����Ѿ�����ˡ�Ȼ����һ���յ�ģ�ͣ�ʹ�� torch.nn.Module ���add_module������յ�ģ���м���ָ���IJ��ģ�飬���õ������Զ����ͼ����Ǩ��ģ�͡�add_module�������ݵIJ����ֱ��Dz�ε����ֺ�ģ�飬��ģ����ʹ�� isinstance ʵ����⺯���õ��ģ��������Ƕ�Ӧ�IJ�Ρ��ڶ����ģ��֮�������д�ӡ����� + +print(new_model) + +����Ľ�����£� + +Sequential( + (Conv_1): Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) + (style_loss_1): Style_loss( + (loss_fn): MSELoss() + (gram): Gram_matrix() + ) + (ReLU_1): ReLU(inplace=True) + (Conv_2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) + (style_loss_2): Style_loss( + (loss_fn): MSELoss() + (gram): Gram_matrix() + ) + (ReLU_2): ReLU(inplace=True) + (MaxPool_3): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False) + (Conv_3): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) + (content_loss_3): Content_loss( + (loss_fn): MSELoss() + ) + (style_loss_3): Style_loss( + (loss_fn): MSELoss() + (gram): Gram_matrix() + ) + (ReLU_3): ReLU(inplace=True) + (Conv_4): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) + (style_loss_4): Style_loss( + (loss_fn): MSELoss() + (gram): Gram_matrix() + ) +) + +���������Dz����Ż��Ĵ��룺 + +input_img = content_img.clone() +parameter = torch.nn.Parameter(input_img.data) + +# �����ģ������Ҫ�Ż�����ʧֵ�ж�����ҹ�ģ�ϴ�ʹ�ø��Ż���������ȡ�ø��õ�Ч���� +optimizer = torch.optim.LBFGS([parameter]) + +2.4 ѵ���¶���ľ��������� +�����ģ�͵Ĵ���Ż������Ķ���󣬾Ϳ��Կ�ʼ����ģ�͵�ѵ���Ͳ������Ż��ˣ��������£� +# ����������ģ��ѵ���Ͳ����Ż� +epoch_n = 300 +epoch = [0] +while epoch[0] <= epoch_n: + + def closure(): + optimizer.zero_grad() + style_score = 0 + content_score = 0 + parameter.data.clamp_(0,1) + new_model(parameter) + for sl in style_losses: + style_score += sl.backward() + + for cl in content_losses: + content_score += cl.backward() + + epoch[0] += 1 + if epoch[0] % 50 == 0: + print('Epoch:{} Style_loss: {:4f} Content_loss: {:.4f}'.format(epoch[0], style_score.data.item(), + content_score.data.item())) + return style_score + content_score + +������optimizer.step(closure) +������ +������ +���������£� +Epoch:50 Style_loss: 8.816691 Content_loss: 1.8809 +Epoch:100 Style_loss: 3.377805 Content_loss: 1.7790 +Epoch:150 Style_loss: 0.531610 Content_loss: 1.8476 +Epoch:200 Style_loss: 0.143326 Content_loss: 1.7222 +Epoch:250 Style_loss: 0.107568 Content_loss: 1.6353 +Epoch:300 Style_loss: 0.099968 Content_loss: 1.6046 + +�������붨��ѵ������Ϊ300�Σ�ʹ�� sl.backward��cl.backwardʵ����ǰ�򴫲��ͺ��򴫲��㷨��ÿ���� 50 ��ѵ���������ʧֵ����һ�δ�ӡ������������������£� + +#�Է��Ǩ��ͼƬ��� +output = parameter.data +unloader = transforms.ToPILImage() + +plt.ion() +plt.figure() +def imshow(tensor, title=None): + image = tensor.clone().cpu() + image = image.view(3, 224, 224) + image = unloader(image) + plt.imshow(image) + if title is not None: + plt.title(title) + plt.pause(0.001) # pause����ͼ����� +imshow(output, title='Output Image') + +#����sphinx_gallery_thumbnail_number = 4 +plt.ioff() +plt.show() + +���֮���ͼƬ���£� + + + +Ч�����У�����ͼƬ�����˷��ͼƬ�ķ�񣬲�����Щ�ط���RGBͨ��������̫�У������Ż��ռ䡣�ȽϺõ����ͼƬ����������ɫ�Ļ����ϻ�����ͼ��������ϣ����ͷ��ͼƬ��Ϊ���ƣ���������ͼ���������Ȼû�з���̫��ı仯�� + + +3 С�� + +ʵ���˻�����ͼ����Ǩ���㷨�����ͼ����Ǩ�ƹ��̵�ʵ�ִ���һ���Ƚ����Ե�ȱ�㣬����ÿ��ѵ��ֻ�ܶ����е�һ�ַ�����Ǩ�ƣ������Ҫ������������Ǩ�ƣ�Ҫ���¶�ģ�ͽ���ѵ����������Ҫͨ�������ݺͷ�����ò�ͬ��Ȩ�������Ʒ����ڵķ�ʽ�����ַ�ʽ��ʵ��Ӧ���в�̫���룬������Ҫ����Ч�����ܵ�ʵ�ַ�ʽ������������ֻ������Щ��ʵ��ѧϰ���˽⵽���ٷ��Ǩ�ƣ�ֻ������ʹ��pytorchʵ�ֵ����ϱȽ��٣�û�гɹ������ô��롣�����Ǻ����Ż�������һЩ�ɹ������������渽�� + + + + + + +��󣬲ο��������£� +https://www.cnblogs.com/subic/p/8110478.html +https://zhuanlan.zhihu.com/p/23479658 +https://blog.csdn.net/qq_17506541/article/details/80012589 +https://blog.csdn.net/u014380165/article/details/76286047 +https://blog.csdn.net/m0_46653437/article/details/108470002?spm=1001.2014.3001.5506 +https://blog.csdn.net/xs1997/article/details/104503934/?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_title~default-0--blog-104502633.pc_relevant_aa&spm=1001.2101.3001.4242.1&utm_relevant_index=3