Transfer Learning Là Gì

  -  
1. Introduction

1.1 Fine-tuning là gì ?

Chắc hẳn hồ hết ai làm việc cùng với những Model vào deep learning đông đảo đang nghe/thân quen với định nghĩa Transfer learning cùng Fine tuning. Khái niệm tổng quát: Transfer learning là tận dụng tối đa trí thức học tập được từ một vấn đề để vận dụng vào 1 vấn đề tất cả liên quan không giống. Một ví dụ solo giản: chũm vị train 1 Model bắt đầu hoàn toàn cho bài xích toán phân một số loại chó/mèo, người ta rất có thể tận dụng tối đa 1 model đã có train ở ImageNet datamix cùng với hằng triệu ảnh. Pre-trained Model này sẽ tiến hành train tiếp bên trên tập dataphối chó/mèo, quy trình train này diễn ra nkhô nóng rộng, công dụng hay tốt rộng. Có rất nhiều đẳng cấp Transfer learning, những bạn cũng có thể tìm hiểu thêm trong bài bác này: Tổng vừa lòng Transfer learning. Trong bài bác này, mình đang viết về 1 dạng transfer learning phổ biến: Fine-tuning.Quý Khách vẫn xem: Transfer learning là gì

Hiểu dễ dàng và đơn giản, fine-tuning là các bạn mang 1 pre-trained mã sản phẩm, tận dụng một trong những phần hoặc toàn bộ những layer, thêm/sửa/xoá 1 vài layer/nhánh để tạo nên 1 model new. Thường những layer đầu của model được freeze (đóng băng) lại - tức weight những layer này đang không bị chuyển đổi giá trị vào quá trình train. Lý bởi vì chưng những layer này sẽ có khả năng trích xuất báo cáo nấc trìu tượng rẻ , khả năng này được học trường đoản cú quy trình training trước đó. Ta freeze lại để tận dụng tối đa được kỹ năng này với góp Việc train diễn ra nhanh hao hơn (mã sản phẩm chỉ buộc phải update weight sinh hoạt những layer cao). Có không hề ít những Object detect model được gây ra dựa vào các Classifier Mã Sản Phẩm. VD Retimãng cầu Mã Sản Phẩm (Object detect) được tạo cùng với backbone là Resnet.

Bạn đang xem: Transfer learning là gì

quý khách sẽ xem: Transfer learning là gì

*

1.2 Tại sao pytorch thay vày Keras ?

Chủ đề nội dung bài viết từ bây giờ, mình vẫn khuyên bảo fine-tuning Resnet50 - 1 pre-trained Model được hỗ trợ sẵn vào torchvision của pytorch. Tại sao là pytorch nhưng chưa hẳn Keras ? Lý vị vì bài toán fine-tuning mã sản phẩm vào keras hết sức đơn giản dễ dàng. Dưới đây là 1 đoạn code minh hoạ mang lại bài toán thi công 1 Unet dựa trên Resnet vào Keras:

from tensorflow.keras import applicationsresnet = applications.resnet50.ResNet50()layer_3 = resnet.get_layer("activation_9").outputlayer_7 = resnet.get_layer("activation_21").outputlayer_13 = resnet.get_layer("activation_39").outputlayer_16 = resnet.get_layer("activation_48").output#Adding outputs decoder with encoder layersfcn1 = Conv2D(...)(layer_16)fcn2 = Conv2DTranspose(...)(fcn1)fcn2_skip_connected = Add()()fcn3 = Conv2DTranspose(...)(fcn2_skip_connected)fcn3_skip_connected = Add()()fcn4 = Conv2DTranspose(...)(fcn3_skip_connected)fcn4_skip_connected = Add()()fcn5 = Conv2DTranspose(...)(fcn4_skip_connected)Unet = Model(inputs = resnet.đầu vào, outputs=fcn5)quý khách có thể thấy, fine-tuning Model trong Keras đích thực khôn cùng đơn giản dễ dàng, dễ có tác dụng, dễ nắm bắt. Việc add thêm những nhánh rất dễ dàng do cú pháp đơn giản và dễ dàng. Trong pytorch thì ngược trở lại, kiến tạo 1 Model Unet tựa như sẽ khá vất vả và phức hợp. Người new học đã gặp mặt trở ngại vày trên mạng không nhiều các lí giải mang lại bài toán này. Vậy bắt buộc bài này bản thân sẽ lí giải cụ thể biện pháp fine-tune vào pytorch để vận dụng vào bài toán thù Visual Saliency prediction

2. Visual Saliency prediction

2.1 What is Visual Saliency ?


*

khi quan sát vào 1 bức ảnh, mắt thường sẽ có Xu thế triệu tập nhìn vào 1 vài ba cửa hàng bao gồm. Ảnh trên đấy là 1 minh hoạ, color đá quý được thực hiện nhằm bộc lộ mức độ thú vị. Saliency prediction là bài xích toán mô phỏng sự triệu tập của đôi mắt tín đồ Lúc quan liêu sát 1 bức ảnh. Cụ thể, bài xích toán thù đòi hỏi xây dừng 1 Mã Sản Phẩm, mã sản phẩm này dìm hình ảnh đầu vào, trả về 1 mask mô rộp mức độ đắm say. vì thế, mã sản phẩm nhấn vào 1 input đầu vào image với trả về 1 mask tất cả kích cỡ tương đương.

Để rõ hơn về bài tân oán này, bạn có thể đọc bài: Visual Saliency Prediction with Contextual Encoder-Decoder Network.Dataphối thịnh hành nhất: SALICON DATASET

2.2 Unet

Note: Quý Khách có thể bỏ qua phần này ví như vẫn biết về Unet

Đây là 1 bài bác tân oán Image-to-Image. Để giải quyết và xử lý bài xích toán thù này, bản thân sẽ xây dựng dựng 1 Model theo bản vẽ xây dựng Unet. Unet là 1 phong cách xây dựng được áp dụng những trong bài xích toán thù Image-to-image như: semantic segmentation, tự động color, super resolution ... Kiến trúc của Unet gồm điểm tương tự như cùng với phong cách thiết kế Encoder-Decoder đối xứng, có thêm những skip connection từ Encode thanh lịch Decode tương ứng. Về cơ phiên bản, những layer càng tốt càng trích xuất thông tin ở mức trìu tượng cao, điều ấy đồng nghĩa với việc các báo cáo mức trìu tượng tốt nhỏng đường nét, Màu sắc, độ phân giải... sẽ ảnh hưởng mất đuối đi vào quy trình lan truyền. Người ta thêm những skip-connection vào nhằm giải quyết và xử lý vấn đề này.

Với phần Encode, feature-map được downscale bằng các Convolution. trái lại, ở chỗ decode, feature-maps được upscale bởi vì các Upsampling layer, trong bài này mình áp dụng những Convolution Transpose.

*

2.3 Resnet

Để giải quyết bài bác toán, bản thân sẽ xây dựng Model Unet cùng với backbone là Resnet50. quý khách hàng buộc phải tìm hiểu về Resnet ví như chưa chắc chắn về bản vẽ xây dựng này. Hãy quan liền kề hình minch hoạ dưới đây. Resnet50 được phân thành các khối hận bự . Unet được thành lập cùng với Encoder là Resnet50. Ta đang lôi ra output của từng khối hận, chế tạo những skip-connection kết nối trường đoản cú Encoder quý phái Decoder. Decoder được tạo vày các Convolution Transpose layer (xen kẽ trong các số đó là những lớp Convolution nhằm mục đích sút số chanel của feature maps -> bớt con số weight mang đến model).

Theo ý kiến cá thể, pytorch rất dễ code, dễ nắm bắt hơn không hề ít so với Tensorflow 1.x hoặc ngang ngửa Keras. Tuy nhiên, vấn đề fine-tuning model trong pytorch lại cạnh tranh hơn rất nhiều đối với Keras. Trong Keras, ta không nên vượt quan tâm tới kiến trúc, luồng cách xử trí của mã sản phẩm, chỉ việc kéo ra các output trên một số ít layer một mực làm cho skip-connection, ghxay nối và tạo ra model mới.

Xem thêm: Khu Vui Chơi Gia Đình Siêu Nhân, Đẹp Độc Lạ Dành Cho Bé Tại Tphcm


*

3. Code

Import những package

import albumentations as Aimport numpy as npimport torchimport torchvisionimport torch.nn as nn import torchvision.transforms as Timport torchvision.models as modelsfrom torch.utils.data import DataLoader, Datasetimport ....

3.1 utils functions

Trong pytorch, tài liệu gồm máy trường đoản cú dimension không giống với Keras/TF/numpy. Đôi khi với numpy tuyệt keras, hình họa bao gồm dimension theo máy tự (batchform size,h,w,chanel)(batchform size, h, w, chanel)(batchsize,h,w,chanel). Thứ từ trong Pytorch ngược trở lại là (batchsize,chanel,h,w)(batchkích cỡ, chanel, h, w)(batchkích cỡ,chanel,h,w). Mình sẽ xây dựng 2 hàm toTensor và toNumpy nhằm biến hóa qua lại giữa nhị format này.

def toTensor(np_array, axis=(2,0,1)): return torch.tensor(np_array).permute(axis)def toNumpy(tensor, axis=(1,2,0)): return tensor.detach().cpu().permute(axis).numpy() ## display one image in notebookdef plot_img(img): ... ## display multi imagedef plot_imgs(imgs): ...

3.2 Define model

3.2.1 Conv & Deconv

Mình sẽ xây dựng 2 function trả về module Convolution với Convolution Transpose (Deconv)

def Deconv(n_đầu vào, n_output, k_size=4, stride=2, padding=1): Tconv = nn.ConvTranspose2d( n_đầu vào, n_output, kernel_size=k_size, stride=stride, padding=padding, bias=False) bloông chồng = return nn.Sequential(*block) def Conv(n_input đầu vào, n_output, k_size=4, stride=2, padding=0, bn=False, dropout=0): conv = nn.Conv2d( n_input, n_output, kernel_size=k_size, stride=stride, padding=padding, bias=False) bloông chồng = return nn.Sequential(*block)

3.2.2 Unet model

Init function: ta vẫn copy những layer đề nghị giữ trường đoản cú resnet50 vào unet. Sau đó khởi chế tạo ra những Conv / Deconv layer với các layer cần thiết.

Xem thêm: Tải Game Road Rash - Game Đua Xe Trên Máy Tính

class Unet(nn.Module): def __init__(self, resnet): super().__init__() self.conv1 = resnet.conv1 self.bn1 = resnet.bn1 self.relu = resnet.relu self.maxpool = resnet.maxpool self.tanh = nn.Tanh() self.sigmoid = nn.Sigmoid() # get some layer from resnet to lớn make skip connection self.layer1 = resnet.layer1 self.layer2 = resnet.layer2 self.layer3 = resnet.layer3 self.layer4 = resnet.layer4 # convolution layer, use to lớn reduce the number of channel => reduce weight number self.conv_5 = Conv(2048, 512, 1, 1, 0) self.conv_4 = Conv(1536, 512, 1, 1, 0) self.conv_3 = Conv(768, 256, 1, 1, 0) self.conv_2 = Conv(384, 128, 1, 1, 0) self.conv_1 = Conv(128, 64, 1, 1, 0) self.conv_0 = Conv(32, 1, 3, 1, 1) # deconvolution layer self.deconv4 = Deconv(512, 512, 4, 2, 1) self.deconv3 = Deconv(512, 256, 4, 2, 1) self.deconv2 = Deconv(256, 128, 4, 2, 1) self.deconv1 = Deconv(128, 64, 4, 2, 1) self.deconv0 = Deconv(64, 32, 4, 2, 1) def forward(self, x): x = self.conv1(x) x = self.bn1(x) x = self.relu(x) skip_1 = x x = self.maxpool(x) x = self.layer1(x) skip_2 = x x = self.layer2(x) skip_3 = x x = self.layer3(x) skip_4 = x x5 = self.layer4(x) x5 = self.conv_5(x5) x4 = self.deconv4(x5) x4 = torch.cat(, dim=1) x4 = self.conv_4(x4) x3 = self.deconv3(x4) x3 = torch.cat(, dim=1) x3 = self.conv_3(x3) x2 = self.deconv2(x3) x2 = torch.cat(, dim=1) x2 = self.conv_2(x2) x1 = self.deconv1(x2) x1 = torch.cat(, dim=1) x1 = self.conv_1(x1) x0 = self.deconv0(x1) x0 = self.conv_0(x0) x0 = self.sigmoid(x0) return x0 device = torch.device("cuda")resnet50 = models.resnet50(pretrained=True)Mã Sản Phẩm = Unet(resnet50)Mã Sản Phẩm.to(device)## Freeze resnet50"s layers in Unetfor i, child in enumerate(Model.children()): if i 7: for param in child.parameters(): param.requires_grad = False

3.3 Dataset and Dataloader

Dataset trả dìm 1 danh sách những image_path cùng mask_dir, trả về image cùng mask tương ứng.

Define MaskDataset

class MaskDataset(Dataset): def __init__(self, img_fns, mask_dir, transforms=None): self.img_fns = img_fns self.transforms = transforms self.mask_dir = mask_dir def __getitem__(self, idx): img_path = self.img_fns img_name = img_path.split("/").split(".") mask_fn = f"self.mask_dir/img_name.png" img = cv2.imread(img_path) mask = cv2.imread(mask_fn) img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) mask = cv2.cvtColor(mask, cv2.COLOR_BGR2GRAY) if self.transforms: sample = "image": img, "mask": mask sample = self.transforms(**sample) img = sample mask = sample # to Tensor img = img/255.0 mask = np.expand_dims(mask, axis=-1)/255.0 mask = toTensor(mask).float() img = toTensor(img).float() return img, mask def __len__(self): return len(self.img_fns)Test dataset

img_fns = glob("./Salicon_dataset/image/train/*.jpg")mask_dir = "./Salicon_dataset/mask/train"train_transform = A.Compose(, height=256, width=256, p=0.4), A.HorizontalFlip(p=0.5), A.Rotate(limit=(-10,10), p=0.6),>)train_dataset = MaskDataset(img_fns, mask_dir, train_transform)train_loader = DataLoader(train_datamix, batch_size=4, shuffle=True, drop_last=True)# Test datasetimg, mask = next(iter(train_dataset))img = toNumpy(img)mask = toNumpy(mask)img = (img*255.0).astype(np.uint8)mask = (mask*255.0).astype(np.uint8)heatmap_img = cv2.applyColorMap(mask, cv2.COLORMAP_JET)combine_img = cv2.addWeighted(img, 0.7, heatmap_img, 0.3, 0)plot_imgs(

3.4 Train model

Vì bài bác toán dễ dàng và để cho dễ nắm bắt, bản thân sẽ train theo cách đơn giản và dễ dàng độc nhất vô nhị, ko validate trong qúa trình train cơ mà chỉ giữ mã sản phẩm sau một số ít epoch tốt nhất định

train_params = optimizer = torch.optlặng.Adam(train_params, lr=0.001, betas=(0.9, 0.99))epochs = 5model.train()saved_dir = "model"os.makedirs(saved_dir, exist_ok=True)loss_function = nn.MSELoss(reduce="mean")for epoch in range(epochs): for imgs, masks in tqdm(train_loader): imgs_gpu = imgs.to(device) outputs = model(imgs_gpu) masks = masks.to(device) loss = loss_function(outputs, masks) loss.backward() optimizer.step()

3.5 Test model

img_fns = glob("./Salicon_dataset/image/val/*.jpg")mask_dir = "./Salicon_dataset/mask/val"val_transsize = A.Compose()Mã Sản Phẩm.eval()val_dataphối = MaskDataset(img_fns, mask_dir, val_transform)val_loader = DataLoader(val_dataset, batch_size=4, shuffle=False, drop_last=True)imgs, mask_targets = next(iter(val_loader))imgs_gpu = imgs.to(device)mask_outputs = model(imgs_gpu)mask_outputs = toNumpy(mask_outputs, axis=(0,2,3,1))imgs = toNumpy(imgs, axis=(0,2,3,1))mask_targets = toNumpy(mask_targets, axis=(0,2,3,1))for i, img in enumerate(imgs): img = (img*255.0).astype(np.uint8) mask_output = (mask_outputs*255.0).astype(np.uint8) mask_target = (mask_targets*255.0).astype(np.uint8) heatmap_label = cv2.applyColorMap(mask_target, cv2.COLORMAP_JET) heatmap_pred = cv2.applyColorMap(mask_output, cv2.COLORMAP_JET) origin_img = cv2.addWeighted(img, 0.7, heatmap_label, 0.3, 0) predict_img = cv2.addWeighted(img, 0.7, heatmap_pred, 0.3, 0) result = np.concatenate((img,origin_img, predict_img),axis=1) plot_img(result)Kết trái thu được: