摘要:皮膚病領域的痛點皮膚病是發生在皮膚和皮膚附屬器官疾病的總稱。皮膚是人體最大的器官,皮膚病的種類不但繁多,多種內臟發生的疾病也可以在皮膚上有表現。
本文為一個使用深度學習經典模型對isic中的惡黑malignant和nevus痣進行分類任務的文章
智能醫療領域是現在一個非?;鸬念I域,使用AI去解決醫療領域的一些痛點現在已經是很多企業和組織正在做或者即將做的一件事情,雖然AI在醫療領域中的落地應用上還不能看到明確的道路,但可以預見各個企業個組織必然會在自己的領域上有更多的成果,有更多的可以落地的應用。
皮膚病是發生在皮膚和皮膚附屬器官疾病的總稱。皮膚是人體最大的器官,皮膚病的種類不但繁多,多種內臟發生的疾病也可以在皮膚上有表現。嚴重的皮膚病,如惡黑,很可能致人死亡,誤診的后果會非常嚴重,癥狀輕的皮膚病,如痣,也許并不能稱之為皮膚病,而是皮損,很多人不選擇去治療。更嚴肅的是很多致死皮膚病和清癥狀皮膚病形態學及其相似,如上面提到的惡黑和痣,去有效的識別疾病,對挽救患者的生命起著至關重要的作用。
解決問題的論文及思路有幸拜讀了谷歌發出的一篇XXX論文,論文地址
先說說論文的思路。這篇論文是在一個公開數據集isic上面進行的訓練和測試,這個數據集包含1萬多張皮膚病圖片,其中包含惡黑和痣這兩種形態學非常相似,但是后果完全不一樣的兩個皮膚鏡下圖片數據集,惡黑是一種可致死的疾病,而痣一般不會有重大影響,但醫學上經常會有惡黑和痣的誤診存在,給患者造成了很大的損害,因此這篇論文中使用了深度神經網絡的方法進行惡黑和痣的識別,也是打開了一個新視野,造成了很大的影響。
論文使用了經典的神經網絡inception_v3,使用在imageNet中已經訓練好的參數進行了遷移學習,論文結果對惡黑的皮膚病圖片識別也達到了92%左右的準確率,在這之后的另外一篇論文XXX中則使用了一個5層的簡單網絡結構,分別在皮膚病圖片的rgb空間、hsv空間和fft空間進行了訓練,得到了三個模型,最終對模型進行了模型融合,對惡黑的預測達到了97%的準確率。
首先,需要搭建一個神經網絡,使用當下最流行的tensorflow進行了網絡結構的搭建和模型的訓練,在tensorflow的slim庫中提供了inception_v3的封裝好的網絡結構,我可以直接使用該網絡結構進行訓練。如下圖,網絡結構
然后,下載isic的數據集(PS:數據集網站竟然不提供現成的下載鏈接,但是提供了可以下載數據的API),然后整理出其中的惡黑和痣的圖片,人為的將他們分成了訓練集和測試集,訓練集數據和測試集數據的比例大致為2:1,訓練集的惡黑大約1500張,痣約為6500張,測試集惡黑大約為750張,痣3000張左右,這里主要采取隨機分配的方式,并沒有刻意去篩選質量好的圖片作為訓練集。
然后,編寫數據讀取方法(我并沒有將圖片轉化為tensorflow推薦的tfrecords文件再去訓練,而是直接讀入圖片訓練),將訓練集數據目錄全部加載,打亂后,每次讀取batch_size個圖片,讀取數據時,用圖片路徑讀取圖片,將256X的圖片resize為224224的大小,并做基本的翻轉和左右變換,
然后,編寫神經網絡訓練的訓練過程,對fearture maps進行softmax,定義損失函數,選擇優化器,編寫驗證方法
然后,使用已經訓練好的inception_v3的模型,進行遷移學習,并在訓練中對驗證集和測試集進行同步輸出結果
最后,學出模型
學習率0.1,batchsize為64,參數初始化采用一定范圍內的正態分布
可喜可賀可喜可賀可喜可賀,最終的結果非常好,對惡黑識別的準確率達到了驚人的50%左右,意不意外,驚不驚喜,之后當然就是例行的優化程序,所謂一天寫網絡,一月調參數就是這樣的。
這之間我發現再這個數據集上面進行遷移學習和重頭開始學習,區別并不大,故之后的訓練都是重頭開始訓練的.
在調參數之前,首先要知道需要調的參數是什么.可以參考下面鏈接,學習率、權重初始化方法,加減網絡層數,增加正則化都是常見的可以調節的參數。
http://blog.csdn.net/qq_20259...
1、 首先是學習率
這是可能在調參數過程中第一個應該調的參數,調整學習率可以調大或者調小。
上面網絡的初始的學習率為0.1,這對很多數據集的分類來說已經夠了,通常來說也不應該有過小的初始化學習率,這通常會導致過擬合,但并不總是這樣,何凱明大神一次接受采訪時說過,在有些情況下即使學習率達到0.000001,也不會過小。也不應該有過大的學習率,這會導致結果在極值點兩邊跳動。
分析訓練結果,基本可以知道我們的學習率過大了。逐漸的降低學習率并逐步對照,觀察訓練結果的變化,發現預測的總體精度確實在上升,在學習率達到0.005時測試集整體平均精度達到了最高,為75%左右,再調小會出現測試集精度下降的情況,且訓練速度變慢。
這一步的訓練結果在測試集上面出現了令人不愉快的表現,召回率非常低,大部分預測都偏向了痣,即惡黑的測試集大部分都預測為了痣,這顯然是不對的。
2、 解決數據的問題
首先,在出現上面的結果后,我查了一些資料,對樣本不均衡有了一些新的認識??紤]當前訓練出現了樣本不均衡,導致訓練出現一些問題.參考文章
在分類中如何處理訓練集中不平衡問題
深度 | 解決真實世界問題:如何在不平衡類上使用機器學習?
一般推薦從增加數據來源開始,但在此例中,因為數據集來源于公開數據集,并且含有惡黑和痣的分類數據的公開數據集幾乎不存在,已不存在增加數據集的可能性。
這時我們考慮使用重采樣和降采樣
1> 首先降采樣,即把痣的訓練集減少到和惡黑一樣,調整了痣數據的訓練集和測試集的比例。繼續訓練,得到的結果在測試集上中,對惡黑的測試精度得到了大幅提升,但對于負樣本痣的精度確下降到合格線以下
2> 然后再采用重采樣的方式,將惡黑的圖片進行復制,將其擴展到和痣的數量相等。繼續訓練,得到的結果正好和降采樣相反,在測試集上,惡黑精度不高,但總體的精度確實比之前高了,這樣的結果同樣也是我們不能接受的
上面出現的兩個極端情況,再一定程度上來說就是發生了欠擬合和過擬合。減少痣的訓練集,導致對痣的訓練出現了欠擬合,對惡黑重采樣,導致對惡黑的訓練出現了過擬合。
那么是否可以通過一定方式生成一些數據呢,考慮原圖是256X的尺寸,考慮采用剪裁的方式而不是通過resize的方式去獲取圖片。對圖片進行預處理,對每一幅圖片從左上角開始,水平方向每隔1個像素進行一次224高度(數據集中高度不固定,但都小于224)的裁剪,并且對高度垂直方向進行了zero padding,然后對生成的圖片進行了水平和垂直方向的隨機翻轉,生成了新的訓練數據集和測試數據集(同樣保持訓練集中正樣本和負樣本數量基本相同)。繼續訓練,情況并沒有多少改善,提升也有限,并且依然是痣的精度明顯高于惡黑的精度.
這個時候我不對數據集產生了懷疑,是不是因為痣的數據集存在一些過大的噪聲干擾呢,于是我將痣的數據集換成脂溢性角化病,即老年斑的數據集進行訓練。
isic數據集中也含有1000多例的脂溢性角化病的數據,比惡黑的數據略少,采用上一次的網絡進行訓練,發現再兩個分類上的精度都可以達到98%以上,于是我再返回對痣的數據集進行了審視,發現其中有一半以上的數據中包含不知是用來干什么用的有色圓圈
我將訓練集中把這部分去除掉,用剩下的數據進行訓練,把帶有有色圓圈的數據先行擱置,對剩余的數據進行訓練(惡黑和痣),發現結果有了明顯的改善, 在惡黑數據集上的召回率可以達到85%左右,準確率達到89%左右。
但實際上我們并沒有達到原論文中的對rgb空間中預測準確率93%的結果,但這個時候訓練集的精度已經達到了99%,已經到了無法再繼續訓練的狀況,繼續訓練就必須考慮提升模型的泛化能力,調整drop率從0.8到0.7、0.6、0.5,沒有明顯提高,就考慮繼續從訓練集下手。
測試集精度低于訓練集精度,這種現象就是過擬合的現象,增強泛化能力就必須減輕過擬合的影響。考慮到上一步中對原圖像每隔1像素進行裁剪獲取訓練集和測試機的方法是不是和之前的重采樣一樣,出現了很大程度的過擬合呢?雖然從一張圖片中新生成的訓練集都不相同,但他們都是從一張原圖中裁剪出來的,對生成的訓練圖像進行訓練是不是相當于對原圖進行了多次訓練呢?
為了驗證這個情況,我調整了生成圖片的間隔,即把每隔1像素裁剪,變成每隔5個像素再去裁剪一次,通過在這種方式生成的訓練數據和測試數據中的實踐,在惡黑的表現召回率可以達到88%左右,準確率達到94.5%左右。同時,考慮到我們的測試集是滑動生成的,預測時是根據原測試集生成的數據預測,但實際要進行的預測則是,對原圖進行滑動裁剪,計算所有裁剪圖片的分類概率分布,統計平均值得出預測結果的方法,那么可以想想最終的預測效果必然會更好(沒有驗證過,但至少結果不會比當前結果差,因為準確率和召回率都超過了50%)
在以上工作的基礎上,繼續采用一些常見的優化模型的方法,如修改常規的梯度下降優化器, 嘗試帶有動量的梯度下降優化器和學習率下降的優化器,嘗試采用不同的激活函數,嘗試使用不同的drop率等常用的優化訓練過程,再訓練和收斂速度上,最終訓練結果再測試集上的表現都有少量的提升
在使用inception_v3進行訓練時,因為inception_v3網絡結構中存在batch_norm,因為之前對batch_norm的不充分了解,導致踩到了一個坑里面。
batch norm在網絡訓練過程中會起到關鍵性的作用,他可以加速訓練過程,并且一定程度上提升模型的效果。原理是在訓練過程中,計算mini-batch的平均值和標準差,對數據進行正則化,將數據約束到一個范圍內,保持他們的平均值和標準差不變,對正則化之后的數據進行訓練,
在學習卷積核和偏置項參數時,同時會學習batch norm的β和γ,但在測試時就完全不同了,在測試時不需要對測試的mini-batch范圍進行約束,只需要使用訓練得到的固化的參數進行預測就行,而我就犯了相同的錯誤。
我起初在訓練和測試的時候沒有要求is_training這個參數,這個參數指定了是要取當前mini-batch的平均值和標準差,還是使用固化的參數,tensorflow中提供的inception_v3網絡的is_training默認為True,所以我在訓練好模型之后做預測時,不同的加載數據方式,總會得到不同的結果,如,順序加載所有類的數據,打亂加載所有類數據,每個mini-batch中各類數量相同等,重新調整了batch_norm后解決(slim.batch_norm有坑,雖然不知道什么原因,但is_training如何設置都會有問題),編寫了一個batch_norm方法解決了這個問題
def batch_norm(x, is_training, decay=0.9, eps=1e-5): shape = x.get_shape().as_list() assert len(shape) in [2, 4] n_out = shape[-1] beta = tf.Variable(tf.zeros([n_out])) gamma = tf.Variable(tf.ones([n_out])) if len(shape) == 2: batch_mean, batch_var = tf.nn.moments(x, [0]) else: batch_mean, batch_var = tf.nn.moments(x, [0, 1, 2]) ema = tf.train.ExponentialMovingAverage(decay=decay) def mean_var_with_update(): ema_apply_op = ema.apply([batch_mean, batch_var]) with tf.control_dependencies([ema_apply_op]): return tf.identity(batch_mean), tf.identity(batch_var) mean, var = tf.cond(is_training, mean_var_with_update, lambda: (ema.average(batch_mean), ema.average(batch_var))) return tf.nn.batch_normalization(x, mean, var, beta, gamma, eps)
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/19665.html
摘要:嚴肅的開場白故事要從深度學習說起。本文從視頻分類的角度,對深度學習在該方向上的算法進行總結。數據集熟悉深度學習的朋友們應該清楚,深度學習是一門數據驅動的技術,因此數據集對于算法的研究起著非常重要的作用。是一個比較成功的傳統方法與深度學習算 showImg(https://segmentfault.com/img/bV7hQP?w=900&h=330); 不嚴肅的開場白 視頻社交已經成為...
閱讀 3138·2021-11-24 10:24
閱讀 2930·2021-11-11 16:54
閱讀 3066·2021-09-22 15:55
閱讀 2027·2019-08-30 15:44
閱讀 1901·2019-08-29 18:41
閱讀 2761·2019-08-29 13:43
閱讀 3053·2019-08-29 12:51
閱讀 1171·2019-08-26 12:19