數據規範-Normalization是深度學習中咱們很容易忽視,也很容易出錯的問題。咱們訓練的全部數據在輸入到模型中的時候都要進行一些規範化。例如在pytorch中,有些模型是經過規範化後的數據進行訓練的,因此咱們在使用這些預訓練好的模型的時候,要注意在將本身的數據投入模型中以前要首先對數據進行規範化。python
在pytorch附帶的模型中咱們能夠選擇預訓練模型:git
import torchvision.models as models
resnet18 = models.resnet18(pretrained=True)
alexnet = models.alexnet(pretrained=True)
squeezenet = models.squeezenet1_0(pretrained=True)
vgg16 = models.vgg16(pretrained=True)
densenet = models.densenet161(pretrained=True)
inception = models.inception_v3(pretrained=True)複製代碼
預訓練模型即模型中的權重參數都被訓練好了,在構造模型後讀取模型權重便可。github
可是有些東西須要注意:網絡
也就是說,模型設計的正確只是第一步,咱們輸入的圖像數據的格式的正確性也是特別重要的,咱們日常輸入的圖像大部分都是三通道RGB彩色圖像,數據範圍大部分都是[0-255],也就是一般意義上的24-bit圖(RGB三通道各8位)。在pytorch中有專門的一些模塊:transforms
模塊來對圖像進行一些預處理操做:dom
transform = transforms.Compose([
transforms.RandomResizedCrop(100),
transforms.RandomHorizontalFlip(),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
])複製代碼
並且在pytorch的官方介紹中也提到了,pytorch使用的預訓練模型搭配的數據必須是:學習
也就是3通道RGB圖像(3 x H x W),並且高和寬最好不低於224(由於拿來作預訓練的模型大小就是224 x 224),而且圖像數據大小的範圍爲[0-1],使用mean和std去Normalize。spa
爲何這樣說官方也說了,由於全部的預訓練模型是使用通過normal後的數據獲得的,因此咱們輸入的數據也必須通過格式化,不然很容易出現損失爆炸。設計
爲何咱們要進行格式化呢?3d
咱們選取一組人臉圖片來舉個例子,這組人臉圖像的格式是這樣的:code
這裏從Labeled faces in the Wild數據集中取出100我的臉圖像,這個數據集中每張圖像對應着一個名字,並且每張圖像的臉都差很少被定位到了中間。
咱們有了這一組數據後,接下來要作的通常是這幾個步驟:
在圖像輸入到神經網絡以前要注意,每張圖都要保證同樣的尺寸和大小。大部分的模型要求輸入的圖像的形狀是正方形,通常都是256 x 25六、128 x 128 、 64 x 64或者其餘的形狀,這種方形是最好進行訓練的。固然其餘形狀也是能夠的,好比長方形,但若是是長方形的話就要注意設計卷積層通道的時候要稍微注意一下。總之,咱們都是先對圖像極性crop,crop成正方形,通常取圖像的中心位置。
好比下面這張人臉圖(256 x 256)就很舒服,呃,由於不用修剪了。
比例也是比較重要的,圖像形狀肯定了,可是有些時候咱們在訓練時隨着卷積層愈來愈深,特徵圖愈來愈小,爲了實現一些功能,咱們所須要的圖像的比例也要稍微改變一下。不管是放大仍是縮小,假如縮小到100像素,咱們就讓上面的圖像乘以0.39(100/256)。可是放大和縮小時都要考慮四捨五入,是floor仍是ceil就各有見地了。
一組圖像集的均值和方差能夠很好地歸納這組圖像的信息和特徵。均值就是一組數據的平均水平,而方差表明的是數據的離散程度。下圖是以前展現的100張人臉圖的均值圖和方差圖,能夠看到左面的均值圖中,明顯看到一個模糊的人臉。而且能夠看出100張人臉圖中,人的臉是分佈在中心的,而右邊的方差圖能夠看到中心顏色偏暗(小於100),四周偏亮(大於100),也就是說明100張圖中,圖像四周的分佈明顯變化比較劇烈。
在這樣Normalize以後,神經網絡在訓練的過程當中,梯度對每一張圖片的做用都是平均的,也就是不存在比例不匹配的狀況。而在normalize以前每張圖片的特徵分佈都是不同的,有的陡峭有的平緩,若是不進行預處理,那麼在梯度降低的時候有些圖片的特徵值比較大而有些則比較小,這樣梯度運算沒法顧及到不一樣特徵不一樣維度不一樣層次的降低趨勢,這樣很難進行訓練,loss會不停的震盪。
說到重點了,咱們在文章最開始說的格式化,其實即便在一組圖中,每一個圖像的像素點首先減去全部圖像均值的像素點,而後再除以方差。這樣能夠保證全部的圖像分佈都類似,也就是在訓練的時候更容易收斂,也就是訓練的更快更好了。另外,不一樣圖像像素點範圍的mean和std是不同的,通常咱們輸入的都是[0-1]或者[0-255]的圖像數據,在pytorch的模型中,輸入的是[0-1],而在caffe的模型中,咱們輸入的是[0-255]。
下面這個圖就是在格式化後的100張人臉圖。
顯然,格式化就是使數據中心對齊,如cs231n中的示例圖,左邊是原始數據,中間是減去mean的數據分佈,右邊是除以std方差的數據分佈,固然cs231n中說除以std其實能夠不去執行,由於只要數據都遵循必定範圍的時候(好比圖像都是[0-255])就沒有必要這樣作了。
有時候須要輸入不是彩色圖,這時候可能須要對數據進行降維操做,也就是RGB->GRAY,固然還有顏色通道和色彩通道的改變,例如RGB->BGR,或者RGB->YUV。顏色通道的改變是爲了實現不一樣的任務和功能,這就要視狀況來決定。
在pytorch的transforms模塊中有不少的變化,均可以用來作數據加強,好比圖像翻轉,旋轉,極座標變換,均可以獲得不一樣的「原始圖」從而加大訓練變量達到很好的訓練效果。這裏很少說,這個須要單獨說明。
文章來源於OLDPAN博客,歡迎來訪:Oldpan博客
歡迎關注Oldpan博客公衆號,持續醞釀深度學習質量文: