安裝pytorch時我們一般都是會一並選擇安裝自帶的視覺模型庫 torchvision , 該庫不僅有經典的視覺模型結構同時還提供了對應參數的下載功能,可以說torchvision庫是十分方便於研究視覺的pytorch使用者來使用的。
給出pytorch的視覺庫torchvision的GitHub地址:
https://github.com/pytorch/vision
該庫中提供的模型結構定義文件:
pytorch官方也給出了對應torchvision庫的一些介紹和使用說明:
https://pytorch.org/vision/stable/models.html
使用隨機權重的torchvision中的視覺模型:
import torchvision.models as models resnet18 = models.resnet18() alexnet = models.alexnet() vgg16 = models.vgg16() squeezenet = models.squeezenet1_0() densenet = models.densenet161() inception = models.inception_v3() googlenet = models.googlenet() shufflenet = models.shufflenet_v2_x1_0() mobilenet_v2 = models.mobilenet_v2() mobilenet_v3_large = models.mobilenet_v3_large() mobilenet_v3_small = models.mobilenet_v3_small() resnext50_32x4d = models.resnext50_32x4d() wide_resnet50_2 = models.wide_resnet50_2() mnasnet = models.mnasnet1_0() efficientnet_b0 = models.efficientnet_b0() efficientnet_b1 = models.efficientnet_b1() efficientnet_b2 = models.efficientnet_b2() efficientnet_b3 = models.efficientnet_b3() efficientnet_b4 = models.efficientnet_b4() efficientnet_b5 = models.efficientnet_b5() efficientnet_b6 = models.efficientnet_b6() efficientnet_b7 = models.efficientnet_b7() regnet_y_400mf = models.regnet_y_400mf() regnet_y_800mf = models.regnet_y_800mf() regnet_y_1_6gf = models.regnet_y_1_6gf() regnet_y_3_2gf = models.regnet_y_3_2gf() regnet_y_8gf = models.regnet_y_8gf() regnet_y_16gf = models.regnet_y_16gf() regnet_y_32gf = models.regnet_y_32gf() regnet_x_400mf = models.regnet_x_400mf() regnet_x_800mf = models.regnet_x_800mf() regnet_x_1_6gf = models.regnet_x_1_6gf() regnet_x_3_2gf = models.regnet_x_3_2gf() regnet_x_8gf = models.regnet_x_8gf() regnet_x_16gf = models.regnet_x_16gf() regnet_x_32gf = models.regnet_x_32gf()
使用torchvision給出的權重及torchvision中的視覺模型:
import torchvision.models as models resnet18 = models.resnet18(pretrained=True) alexnet = models.alexnet(pretrained=True) vgg16 = models.vgg16(pretrained=True) squeezenet = models.squeezenet1_0(pretrained=True) densenet = models.densenet161(pretrained=True) inception = models.inception_v3(pretrained=True) googlenet = models.googlenet(pretrained=True) shufflenet = models.shufflenet_v2_x1_0(pretrained=True) mobilenet_v2 = models.mobilenet_v2(pretrained=True) mobilenet_v3_large = models.mobilenet_v3_large(pretrained=True) mobilenet_v3_small = models.mobilenet_v3_small(pretrained=True) resnext50_32x4d = models.resnext50_32x4d(pretrained=True) wide_resnet50_2 = models.wide_resnet50_2(pretrained=True) mnasnet = models.mnasnet1_0(pretrained=True) efficientnet_b0 = models.efficientnet_b0(pretrained=True) efficientnet_b1 = models.efficientnet_b1(pretrained=True) efficientnet_b2 = models.efficientnet_b2(pretrained=True) efficientnet_b3 = models.efficientnet_b3(pretrained=True) efficientnet_b4 = models.efficientnet_b4(pretrained=True) efficientnet_b5 = models.efficientnet_b5(pretrained=True) efficientnet_b6 = models.efficientnet_b6(pretrained=True) efficientnet_b7 = models.efficientnet_b7(pretrained=True) regnet_y_400mf = models.regnet_y_400mf(pretrained=True) regnet_y_800mf = models.regnet_y_800mf(pretrained=True) regnet_y_1_6gf = models.regnet_y_1_6gf(pretrained=True) regnet_y_3_2gf = models.regnet_y_3_2gf(pretrained=True) regnet_y_8gf = models.regnet_y_8gf(pretrained=True) regnet_y_16gf = models.regnet_y_16gf(pretrained=True) regnet_y_32gf = models.regnet_y_32gf(pretrained=True) regnet_x_400mf = models.regnet_x_400mf(pretrained=True) regnet_x_800mf = models.regnet_x_800mf(pretrained=True) regnet_x_1_6gf = models.regnet_x_1_6gf(pretrained=True) regnet_x_3_2gf = models.regnet_x_3_2gf(pretrained=True) regnet_x_8gf = models.regnet_x_8gf(pretrained=True) regnet_x_16gf = models.regnet_x_16gf(pretrained=True) regnet_x_32gf = models.regnet_x_32gf(pretrained=True)
有一點需要注意,那就是這些模型的預訓練參數都是對數據進行正則化后再進行訓練的,官方具體說明:
不過對於為什么要采用該種方式進行正則數據只給出了簡單解釋,這里我們暫且可以認為該種正則方式是習慣操作或慣例操作。
import torch from torchvision import datasets, transforms as T transform = T.Compose([T.Resize(256), T.CenterCrop(224), T.ToTensor()]) dataset = datasets.ImageNet(".", split="train", transform=transform) means = [] stds = [] for img in subset(dataset): means.append(torch.mean(img)) stds.append(torch.std(img)) mean = torch.mean(torch.tensor(means)) std = torch.mean(torch.tensor(stds))
官方給出的解釋是當時他們最原始編寫代碼時計算了一下數據集的均值與方差,然后並一直用這個數字來進行計算了。
mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]
從代碼:
transform = T.Compose([T.Resize(256), T.CenterCrop(224), T.ToTensor()]) dataset = datasets.ImageNet(".", split="train", transform=transform)
中可以看到官方原始操作時是將數據集中的數據進行resize,crop操作后在進行均值和方差計算的。
for img in subset(dataset):
means.append(torch.mean(img))
stds.append(torch.std(img))
分別求每張圖片R G B三色中每一色像素的均值與方差。
mean = torch.mean(torch.tensor(means)) std = torch.mean(torch.tensor(stds))
對所有圖片的R G B均值與方差求數據集范圍的統計均值,最終得到:
mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]
官方給出補充解釋:
Unfortunately, the concrete subset that was used is lost. For more information see this discussion or these experiments.
也就是原始數據集已經找不到了,但是我們即使使用其他數據集也已然按照慣例使用這個均值與方差,如果自己的數據集本身過小那么自己重新求這個均值與方差可能導致泛化性降低,而如果使用大數據集的話進行如此計算也十分耗計算資源,這可能也是領域內現在也慣例使用這個均值方差來進行數據正則的原因。
官方給出說明,對於 EfficientNet 網絡來說模型的尺寸與變量有關。不過個人解讀就是不同版本的EfficientNet模型其crop及input的size也是不同的,具體的size如下給出:
The sizes of the EfficientNet models depend on the variant. For the exact input sizes check here
例子中的代碼設置:
====================================================