1. 程式人生 > >【番外篇】聊一聊深度學習中的資料增強與實現

【番外篇】聊一聊深度學習中的資料增強與實現

深度學習的訓練往往需要海量的資料,而如今資料又是如此的寶貴(如醫學影象),因此如何利用有效的資料獲得更好的效果呢?資料增強(data augmentation)就是一種常用的方法。

工欲善其事必先利其器。

先來看下實現本文資料增強所需要的必要環境:

  • python3.5
  • keras 2.0.4
  • skimage 0.13.0

溫馨提醒:如果哪位小夥伴使用的不是這些庫,可能要對程式碼稍加修改哈~

這裡有哪些資料增強的看頭呢?

  1. resize
  2. rescale
  3. noise
  4. flip
  5. rotate
  6. shift
  7. zoom
  8. shear
  9. contrast
  10. channel shift
  11. PCA

乾貨來嘍~

1 修改圖片尺寸(resize)

skimage.transform.resize(image, output_shape, order=1, mode=None, cval=0, clip=True, preserve_range=False)

  • image:需要改變尺寸的圖片
  • output_shape:輸出圖片的尺寸(height,weight)
  • 返回resize之後的圖片

程式碼:

img = imread('car.jpg')
resized_image = resize(img,(1024,1280))
imshow(resized_image)

結果:

可以看到,圖片現在的尺寸為1024x1280

2 按比例縮放(rescale)

skimage.transform.rescale(image, scale, order=1, mode=None, cval=0, clip=True, preserve_range=False, multichannel=None)

  • scale:可以是單個的float數,表示縮放的倍數,也可以是一個float型的tuple,如[0.6,0.5],表示將height和weight分別縮放為原來的0.6倍和0.5倍。
img = imread('car.jpg')
rescaled_img = rescale(img,[0.6,0.5])
imshow(rescaled_img)

結果:

rescale後的尺寸大小為768x959。

3 加噪(noise)

利用numpy.random.randint來生成隨機數噪聲。

import numpy as np
height,weight,channel = img.shape

#隨機生成5000個椒鹽噪聲
for i in range(5000):
    x = np.random.randint(0,height)
    y = np.random.randint(0,weight)
    img[x ,y ,:] = 255

imshow(img)
用img[x,y,:]=255這句來對畫素值進行修改,將原來的三通道畫素值,變為255,引自部落格

結果如下:

4 反轉(flip)

skimage沒有提供專門的flip模組,所以需要自己寫。作者是這樣回覆的:

Thanks for helping out, @swiftdiaries. Since this is a NumPy array operation, we'll not include that functionality for now.

幸運的是圖片就是陣列資料,所以我們可以藉助numpy.flip模組。 
垂直翻轉:

import numpy as np
from skimage.io import imread,imshow
img = imread('car.jpg')
vertical_flip = img[::-1,:,:]
imshow(vertical_flip)

結果:

水平翻轉:

horizontal_flip = img[:,::-1,:]
imshow(horizontal_flip)

5 旋轉(rotate)

skimage.ransform.rotate(image, angle, resize=False, center=None, order=1, mode='constant', cval=0, clip=True, preserve_range=False)

  • angle:按照逆時針方向旋轉的角度
  • resize:旋轉角度時是否改變圖片尺寸
  • center:旋轉中心,預設中心為center=(heighr / 2 - 0.5, weight / 2 - 0.5)
from skimage.transform import rotate
img = imread('car.jpg')
rotate_img = rotate(img,30)#逆時針旋轉30°
imshow(rotate_img)

結果:

周圍有太多黑色畫素點,如果這個用於我們的資料增強,效果就大打折扣了,所以可以這樣:

from keras.preprocessing import image

def rotate(x, theta, row_axis=0, col_axis=1, channel_axis=2, fill_mode='nearest', cval=0.):
rotation_matrix = np.array([[np.cos(theta), -np.sin(theta), 0],
[np.sin(theta), np.cos(theta), 0],
[0, 0, 1]])
h, w = x.shape[row_axis], x.shape[col_axis]
transform_matrix = image.transform_matrix_offset_center(rotation_matrix, h, w)
x = image.apply_transform(x, transform_matrix, channel_axis, fill_mode, cval)
return x

rotate_limit=(-30, 30)
theta = np.pi / 180 * np.random.uniform(rotate_limit[0], rotate_limit[1]) #逆時針旋轉角度
#rotate_limit= 30 #自定義旋轉角度
#theta = np.pi /180 *rotate_limit #將其轉換為PI
img_rot = rotate(img, theta)
imshow(img_rot)

這裡呼叫了keras.preprocessing.image.tansform這個函式,該函式可以按照特定的矩陣對圖片進行轉換。(下文的呼叫同理)

結果:

6 平移(shift)

from keras.preprocessing import image #按照特定的矩陣對圖片進行轉換

def shift(x, wshift, hshift, row_axis=0, col_axis=1, channel_axis=2, fill_mode='nearest', cval=0.):
    h, w = x.shape[row_axis], x.shape[col_axis] #讀取圖片的高和寬
    tx = hshift * h #高偏移大小,若不偏移可設為0,若向上偏移設為正數
    ty = wshift * w #寬偏移大小,若不偏移可設為0,若向左偏移設為正數
    translation_matrix = np.array([[1, 0, tx],
                                  [0, 1, ty],
                                  [0, 0, 1]])
    transform_matrix = translation_matrix  
    x = image.apply_transform(x, transform_matrix, channel_axis, fill_mode, cval)
    return x

w_limit=(-0.2, 0.2)
h_limit=(-0.2, 0.2)
wshift = np.random.uniform(w_limit[0], w_limit[1]) 
hshift = np.random.uniform(h_limit[0], h_limit[1]) 
#wshift = 0.1 #自定義平移尺寸
#hshift = 0.1 #自定義平移尺寸

img_shift = shift(img, wshift, hshift)
imshow(img_shift)

結果:

如圖這裡分別向左和向上偏移原尺寸的0.1倍。

7 縮放變換(zoom)

def zoom(x, zx, zy, row_axis=0, col_axis=1, channel_axis=2, fill_mode='nearest', cval=0.):
    zoom_matrix = np.array([[zx, 0, 0],
                            [0, zy, 0],
                            [0, 0, 1]])
    h, w = x.shape[row_axis], x.shape[col_axis]
    transform_matrix = image.transform_matrix_offset_center(zoom_matrix, h, w) #保持中心座標不改變
    x = image.apply_transform(x, transform_matrix, channel_axis, fill_mode, cval)
    return x

zoom_range=(0.7, 1)
zx, zy = np.random.uniform(zoom_range[0], zoom_range[1], 2)

#zx = 0.5
#zy = 0.5 #自定義zoom尺寸
img_zoom = zoom(img, zx, zy)

imshow(img_zoom)

結果:

注意:儘管zoom和resale都按比例對影象進行了縮放,但是當前景位於圖片中央時,zoom可以去掉無用的背景,即保持中心不變,當然,這個還要得益於image.transform_matrix_offset_center函式。

8 剪下(shear)

實現程式碼如下:

def shear(x, shear, row_axis=0, col_axis=1, channel_axis=2, fill_mode='nearest', cval=0.):
    shear_matrix = np.array([[1, -np.sin(shear), 0],
                            [0, np.cos(shear), 0],
                            [0, 0, 1]])
    h, w = x.shape[row_axis], x.shape[col_axis]
    transform_matrix = image.transform_matrix_offset_center(shear_matrix, h, w)
    x = image.apply_transform(x, transform_matrix, channel_axis, fill_mode, cval)
    return x

intensity = 0.5
sh = np.random.uniform(-intensity, intensity) #逆時針方向剪下強度為正

img_shear = shear(img, sh)

imshow(img_shear)

結果如下:

9 對比度變換(contrast)

在影象的HSV顏色空間,改變H,S和V亮度分量,增加光照變化。 
實現如下:

from skimage import color

def randomHueSaturationValue(image, hue_shift_limit=(-180, 180),
                            sat_shift_limit=(-255, 255),
                            val_shift_limit=(-255, 255), u=0.5):
    if np.random.random() < u:
        img = color.rgb2hsv(image)
        h, s ,v = img[:,:,0],img[:,:,1],img[:,:,2]
        hue_shift = np.random.uniform(hue_shift_limit[0], hue_shift_limit[1])

        h = h + hue_shift

        sat_shift = np.random.uniform(sat_shift_limit[0], sat_shift_limit[1])
        s = s + sat_shift

        val_shift = np.random.uniform(val_shift_limit[0], val_shift_limit[1])
        v = v + val_shift

        img[:,:,0],img[:,:,1],img[:,:,2] = h, s ,v

        image = color.hsv2rgb(img)

    return image

contrast_img = randomHueSaturationValue(img)
imshow(img)

結果顯示:

10 隨機通道偏移(channel shift)

def random_channel_shift(x, intensity, channel_index=0):
    x = np.rollaxis(x, channel_index, 0)
    min_x, max_x = np.min(x), np.max(x)
    channel_images = [np.clip(x_channel + np.random.uniform(-intensity, intensity), min_x, max_x)
                      for x_channel in x]
    x = np.stack(channel_images, axis=0)
    x = np.rollaxis(x, 0, channel_index+1)
    return x
img_chsh = random_channel_shift(img, intensity = 0.05)

imshow(img_chsh)

結果:

11 PCA

程式碼如下:

def RGB_PCA(images):
    pixels = images.reshape(-1, images.shape[-1])
    idx = np.random.random_integers(0, pixels.shape[0], 1000000)
    pixels = [pixels[i] for i in idx]
    pixels = np.array(pixels, dtype=np.uint8).T
    m = np.mean(pixels)/256.
    C = np.cov(pixels)/(256.*256.)
    l, v = np.linalg.eig(C)
    return l, v, m


def RGB_variations(image, eig_val, eig_vec):
    a = np.random.randn(3)
    v = np.array([a[0]*eig_val[0], a[1]*eig_val[1], a[2]*eig_val[2]])
    variation = np.dot(eig_vec, v)
    return image + variation

l,v,m = RGB_PCA(img)
img = RGB_variations(img,l,v)
imshow(img)

結果:

相關推薦

深度學習資料增強實現

深度學習的訓練往往需要海量的資料,而如今資料又是如此的寶貴(如醫學影象),因此如何利用有效的資料獲得更好的效果呢?資料增強(data augmentation)就是一種常用的方法。 工欲善其事必先利其器。 先來看下實現本文資料增強所需要的必要環境: python3.5

ASP.NET MVC快速入門之免費jQuery控件庫(MVC5+EF6)

south ade 批量刪除 HP 存儲 重新 mode eve 穩定 目錄 【第一篇】ASP.NET MVC快速入門之數據庫操作(MVC5+EF6) 【第二篇】ASP.NET MVC快速入門之數據註解(MVC5+EF6) 【第三篇】ASP.NET MVC快速入門之安全策略

Java微信公眾平臺開發(七)--公眾平臺測試帳號的申請

轉自;http://www.cuiyongzhi.com/post/45.html 前面幾篇一直都在寫一些比較基礎介面的使用,在這個過程中一直使用的都是我個人微博認證的一個個人賬號,原本準備這篇是寫【多媒體訊息回覆】的,後來主要到我個人賬號的介面許可權不夠,所以在這裡插入一篇【公眾平臺測試帳號的申請】的文章

Java微信公眾平臺開發(十四)--微信web開發者工具使用

str weixin ron log 返回 nbsp 地址欄 alt 直接 轉自:http://www.cuiyongzhi.com/post/58.html 為幫助開發者更方便、更安全地開發和調試基於微信的網頁,微信推出了 web 開發者工具。它是一個桌面應用,通過模擬微

ASP.NET MVC快速入門之免費jQuery控制元件庫(MVC5+EF6)

目錄 FineUIMvc簡介 FineUIMvc 是基於 jQuery 的專業 ASP.NET MVC 控制元件庫,其前身是基於 WebForms 的開源控制元件庫 FineUI(歷時9年120多個版本)。FineUIMvc(基礎版)包含開源版的全部功能,支援 30 種內建主題和 

PostCSS自學筆記(二)

利用PostCSS解決移動端REM適配問題 上一期有提到結合postcss-px2rem外掛來處理移動端適配的方案,以及相關的避坑方法,之後總覺得這個解決方案問題太多,也就誕生了另一套方案運用postcss-pxtorem外掛來進行處理。 那麼這期番外篇講的就是postcss-px2rem和

解憂使用eNSP搭建小型WLAN局域網實驗

華為認證 無線局域網 WLAN 前言 本次實驗使用eNSP中AC6005,AP6050完成實驗。所有配置在AC1上完成。 實驗拓撲 配置過程 一、配置AC1上端口VLAN的配置其中VLAN 100為業務VLAN,VLAN 101為管理VLAN。配置AC鏈接AP的端口為trunk,並修改PVID為

xv6學習記憶體管理

An approach to space management that provides even further simplification of space-management software is to maintain a one-to-one correspondence between s

源碼閱讀Mimikatz鍵獲取遠程終端憑據獲取明文密碼

null nbc pac data dex lsa mod pro package 1、前言 mimikatz框架是非常精妙的,粗淺講一下修改的思路。 它的模塊主要由各個結構體數組組成,根據傳入的命令搜索執行相應命令的模塊 mimikatz.c 部分代碼: NTSTATUS

第七SAP ABAP7.50新語法之F4增強

公眾號:SAP Technical 本文作者:matinal 原文出處: http://www.cnblogs.com/SAPmatinal/ 原文連結: SAP ABAP7.5x系列之F4增強   前言部分 在ABAP專案裡面,F4搜尋幫助是最常用的功能,

Django學習第17:Django之訊號 django的訊號

django中的訊號 Django中的訊號及其用法 Django中提供了"訊號排程",用於在框架執行操作時解耦.

深度學習深度學習的weight initialization

  先說一下幹嗎了? 感謝: https://zhuanlan.zhihu.com/p/34879333 Batch Normalization原理與實戰 https://www.leiphone.com/news/201703/3qMp45aQtbxTdzmK.ht

讀書精華分享《分散式實時處理系統 原理、架構實現》盧譽聲著/2016年

【分享說明】: 我會花很多時間或淺或深的研讀一本書,然後總結一些提煉出來的精華,用簡短的語言,讓其他人能夠用很少的時間大致知道這本書能帶給自己的價值,如果適用自己,鼓勵買一本正本實體書細讀

深度學習資料集很小是種什麼樣的體驗

# 前言 今天提一個比較輕鬆的話題,簡單探討資料集大小對深度學習訓練的影響。 不知道大家有沒有看過這篇文章:[Don't use deep learning your data isn't that big](https://simplystatistics.org/2017/05/31/deeplearni

轉載C#的Equals()和GetHashCode()方法

table rule != tle 繼承 操作符 內存 png blog 首先先談一下Equals()這個方法: Equals()方法,來自於Object,是我們經常需要重寫的方法。此方法的默認實現大概是這樣的: public virtual bool Equals(obj

資料結構stl應用(1)優先佇列

stl是一種重要技巧,可以極大地簡化程式設計過程 在總結stl之前,我們先簡單介紹一下迭代器。 迭代器可以簡單理解為地址的等價物。 在不同資料型別中迭代器支援的操作略有不同 其中vector使用的是隨機訪問迭代器,其支援的操作可以參考上述表格 雖然本文用不上預備知識,但是還是先說一下吧 接

測職業發展

導言: 在做測試迷茫的適合,不妨看看這個文章,來自曉光大神,需要細細拜讀多次,對於自己的測試職業發展會有醍醐灌頂,撥雲見霧的幫助!   老生常談,再談談測試職業發展 有這麼個普遍現象 測試招聘者,特別是一、二線網際網路公司的招聘者最苦惱的事兒就是招人。想找到一個合適的人難於上青天,每天各種

其他學習 cookie,做大專案必懂的知識點

咱們不搞一開始就一大堆理論知識介紹,怕把人講懵了...... 咱們換一個思維方式——"從現象看本質",先說說我們看到了什麼,再從看到的現象中提出問題,最後深入尋找答案。 我們看到的 cookie 我自己建立了一個網站,網址為http://ppsc.sankuai.c

演算法演算法初步:常見排序的演算法

在一個工程中一旦建立了某一個數據庫後,就可能需要對資料庫中資料進行不同方式的排序,比如對姓名進行字母排序,年齡進行大小排序等等。排序在程式設計中非常的重要,但又可能十分的複雜。這篇博文主要介紹一下幾種簡單而且常見的排序演算法。 如何排序 讓我們假設一個場

python全棧開發第九Python常用模塊(主要是re正則和collections)

順序 常用模塊 內置 object 簡潔 整體 re.search lec 快速 一、認識模塊    什麽是模塊:一個模塊就是一個包含了python定義和聲明的文件,文件名就是加上.py的後綴,但其實import加載的模塊分為四個通用類別 :     1.使用python