Pemindahan gaya imej ialah teknologi berasaskan pembelajaran mendalam yang boleh memindahkan gaya satu imej kepada imej lain. Dalam beberapa tahun kebelakangan ini, teknologi pemindahan gaya imej telah digunakan secara meluas dalam bidang seni dan filem dan kesan khas televisyen. Dalam artikel ini, kami akan memperkenalkan cara melaksanakan migrasi gaya imej menggunakan bahasa Python.
1. Apakah pemindahan gaya imej
Pemindahan gaya imej boleh memindahkan gaya satu imej ke imej lain. Gaya boleh menjadi gaya lukisan artis, gaya penggambaran jurugambar, atau gaya lain. Matlamat pemindahan gaya imej adalah untuk mengekalkan kandungan imej asal sambil memberikan gaya baharu.
Teknologi pemindahan gaya imej ialah teknologi pembelajaran mendalam berdasarkan rangkaian saraf konvolusi (CNN) Idea terasnya ialah untuk mengekstrak kandungan dan maklumat gaya imej melalui model CNN yang telah terlatih, dan menggunakan kaedah pengoptimuman. untuk menggabungkan kedua-duanya atau digubah menjadi imej baharu. Lazimnya, maklumat kandungan imej diekstrak melalui lapisan konvolusi dalam CNN, manakala maklumat gaya imej diekstrak melalui korelasi antara inti konvolusi CNN.
2. Laksanakan migrasi gaya imej
Langkah utama untuk melaksanakan migrasi gaya imej dalam Python termasuk memuatkan imej, prapemprosesan imej, membina model, mengira fungsi kehilangan, menggunakan kaedah pengoptimuman untuk lelaran dan Hasil keluaran . Seterusnya, kami akan membincangkan langkah demi langkah ini.
Mula-mula, kita perlu memuatkan imej asal dan imej rujukan. Imej asal ialah imej yang perlu dipindahkan gaya, dan imej rujukan ialah imej gaya yang hendak dipindahkan. Memuatkan imej boleh dilakukan menggunakan modul PIL (Python Imaging Library) Python.
from PIL import Image import numpy as np # 载入原始图像和参考图像 content_image = Image.open('content.jpg') style_image = Image.open('style.jpg') # 将图像转化为numpy数组,方便后续处理 content_array = np.array(content_image) style_array = np.array(style_image)
Praproses termasuk menukar imej asal dan imej rujukan kepada format yang boleh diproses oleh rangkaian saraf, iaitu menukar imej kepada Tensor dan melaksanakan penyeragaman pada masa yang sama . Di sini, kami menggunakan modul prapemprosesan yang disediakan oleh PyTorch untuk melengkapkan.
import torch import torch.nn as nn import torchvision.transforms as transforms # 定义预处理函数 preprocess = transforms.Compose([ transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) ]) # 将图像进行预处理 content_tensor = preprocess(content_image).unsqueeze(0).to(device) style_tensor = preprocess(style_image).unsqueeze(0).to(device)
Model pemindahan gaya imej boleh menggunakan model yang telah dilatih pada pangkalan data imej berskala besar termasuk VGG19 dan ResNet. Di sini kami menggunakan model VGG19 untuk melengkapkan. Mula-mula, kita perlu memuatkan model VGG19 yang telah dilatih dan mengalih keluar lapisan terakhir yang disambungkan sepenuhnya, hanya meninggalkan lapisan konvolusi. Kemudian, kita perlu melaraskan maklumat kandungan dan maklumat gaya imej dengan mengubah suai pemberat lapisan konvolusi.
import torchvision.models as models class VGG(nn.Module): def __init__(self, requires_grad=False): super(VGG, self).__init__() vgg19 = models.vgg19(pretrained=True).features self.slice1 = nn.Sequential() self.slice2 = nn.Sequential() self.slice3 = nn.Sequential() self.slice4 = nn.Sequential() self.slice5 = nn.Sequential() for x in range(2): self.slice1.add_module(str(x), vgg19[x]) for x in range(2, 7): self.slice2.add_module(str(x), vgg19[x]) for x in range(7, 12): self.slice3.add_module(str(x), vgg19[x]) for x in range(12, 21): self.slice4.add_module(str(x), vgg19[x]) for x in range(21, 30): self.slice5.add_module(str(x), vgg19[x]) if not requires_grad: for param in self.parameters(): param.requires_grad = False def forward(self, x): h_relu1 = self.slice1(x) h_relu2 = self.slice2(h_relu1) h_relu3 = self.slice3(h_relu2) h_relu4 = self.slice4(h_relu3) h_relu5 = self.slice5(h_relu4) return h_relu1, h_relu2, h_relu3, h_relu4, h_relu5 device = torch.device("cuda" if torch.cuda.is_available() else "cpu") model = VGG().to(device).eval()
Memandangkan matlamat pemindahan gaya imej adalah untuk mengekalkan kandungan imej asal sambil memberikannya gaya baharu, kita perlu menentukan fungsi kerugian untuk mencapai matlamat ini. Fungsi kehilangan terdiri daripada dua bahagian, satu kehilangan kandungan dan satu lagi kehilangan gaya.
Kehilangan kandungan boleh ditakrifkan dengan mengira ralat min kuasa dua antara imej asal dan imej yang dijana dalam peta ciri lapisan konvolusi. Kehilangan gaya ditakrifkan dengan mengira ralat min kuasa dua antara matriks Gram antara peta ciri imej yang dijana dan imej gaya dalam lapisan konvolusi. Matriks Gram di sini ialah matriks korelasi antara kernel lilitan peta ciri.
def content_loss(content_features, generated_features): return torch.mean((content_features - generated_features)**2) def gram_matrix(input): batch_size , h, w, f_map_num = input.size() features = input.view(batch_size * h, w * f_map_num) G = torch.mm(features, features.t()) return G.div(batch_size * h * w * f_map_num) def style_loss(style_features, generated_features): style_gram = gram_matrix(style_features) generated_gram = gram_matrix(generated_features) return torch.mean((style_gram - generated_gram)**2) content_weight = 1 style_weight = 1000 def compute_loss(content_features, style_features, generated_features): content_loss_fn = content_loss(content_features, generated_features[0]) style_loss_fn = style_loss(style_features, generated_features[1]) loss = content_weight * content_loss_fn + style_weight * style_loss_fn return loss, content_loss_fn, style_loss_fn
Selepas mengira fungsi kehilangan, kita boleh menggunakan kaedah pengoptimuman untuk melaraskan nilai piksel imej yang dihasilkan untuk meminimumkan fungsi kehilangan. Kaedah pengoptimuman yang biasa digunakan termasuk kaedah penurunan kecerunan dan algoritma L-BFGS. Di sini, kami menggunakan pengoptimum LBFGS yang disediakan oleh PyTorch untuk melengkapkan pemindahan imej. Bilangan lelaran boleh dilaraskan mengikut keperluan Biasanya, 2000 lelaran boleh mendapat hasil yang lebih baik.
from torch.optim import LBFGS generated = content_tensor.detach().clone().requires_grad_(True).to(device) optimizer = LBFGS([generated]) for i in range(2000): def closure(): optimizer.zero_grad() generated_features = model(generated) loss, content_loss_fn, style_loss_fn = compute_loss(content_features, style_features, generated_features) loss.backward() return content_loss_fn + style_loss_fn optimizer.step(closure) if i % 100 == 0: print('Iteration:', i) print('Total loss:', closure().tolist())
Akhir sekali, kami boleh menyimpan imej yang dijana secara setempat dan memerhatikan kesan migrasi gaya imej.
import matplotlib.pyplot as plt generated_array = generated.cpu().detach().numpy() generated_array = np.squeeze(generated_array, 0) generated_array = generated_array.transpose(1, 2, 0) generated_array = np.clip(generated_array, 0, 1) plt.imshow(generated_array) plt.axis('off') plt.show() Image.fromarray(np.uint8(generated_array * 255)).save('generated.jpg')
3. Ringkasan
Artikel ini memperkenalkan cara menggunakan bahasa Python untuk melaksanakan teknologi pemindahan gaya imej. Dengan memuatkan imej, pra-memproses imej, membina model, mengira fungsi kehilangan, lelaran dengan kaedah pengoptimuman dan mengeluarkan hasilnya, kita boleh memindahkan gaya satu imej kepada yang lain. Dalam aplikasi praktikal, kita boleh melaraskan parameter seperti imej rujukan dan bilangan lelaran mengikut keperluan yang berbeza untuk mendapatkan hasil yang lebih baik.
Atas ialah kandungan terperinci Contoh migrasi gaya imej dalam Python. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!