自分のための備忘録的なブログです。

Ubuntu14.04LTS を使って、ディープラーニングの勉強をしています。
記載されているコードは、他の OS には互換性がない可能性があります。


DNN:
マシン性能別 学習速度の比較, TFチュートリアルをmodifyする

python3:
オブジェクト指向プログラミングとは, モジュールとインポート、パスを通す, システムコマンド(os), ファイル・フォルダ名取得, 画像の前処理,

Ubuntu14 の初期設定:
Ubuntu14初期設定, 初期設定-2, cudaなども, 初期設定-3

日記、最近の進捗

 

 このところ、  CNN を使った画像分類の勉強をしていました。

 f:id:pmonty:20170718032024p:plain

 

 Qiita のコードを参考に 2クラス分類を Tensorflow で実装。

 医用画像で 85% の accuracy ・・・せめて 90% 欲しいのに。 Data augmentation や、層を深くするなど試したけど、どれもこれもダメでした。

 なお、Cifar-10 のチュートリアルを参考にしたので、画像は 32 x 32 に圧縮・・・これが良くないかも。解像度高いほうが成績はいいだろうから、落ち着いたら圧縮せずに試してみる。

 

 で、このスランプの時に、知識をつけようと、Python や 画像認識関連、プログラミング一般論の本などを乱読。

 いくつかの本はすごく役に立った。

 紙の本、Kindleなど色々読んだけど、中でもオライリーの e ブック が最高だった。

 

 最近こんなエントリがはてブで人気を博してましたが

www.kotsulog.com

 オライリーの e ブックは、紙の本より安い(同額の本もあり)。

 基本は pdf、epub、mobi などのフォーマットで提供されているが、一部の本は pdf しか提供されていないので注意。

 

 ここ半年でプログラミング関連の本がかなり増えた。プログラミングの本って辞書的に使うことが多いので、持ち運びやすい電子書籍のほうがいい。

 オライリーの e ブックは mobi 形式もあって Kindle などの電子ペーパー端末でも読めるし最高。

 

 さて、そんなこんなで以前からやってみたかった Chainer にも挑戦。

 

 Qiita のコード参考に CNN を作成。違ったタスク(120枚の画像で2クラス分類)で、accuracy 100%, (ベストの値)。

 良かった、過学習かもしれないけど。

 

 こんな感じ。 

f:id:pmonty:20170716023821p:plain

 

 

 

 で、 Tensorflow と Chainer を少し触ってみた感想。

 

1.DNN はデータ入力が大変

 Deep learning のコードはネット上にたっくさんある。 Neural network の作成や deep learning 自体は、私のような初心者でも可能。

 ただ、データを NN に入るように整形して、learning を始めるまでが大変。データの取り回し方法もネット上に多数の記事があるのだけど、自分の作った NN に合うような形で実装しないといけない。

 機械学習を長くやってきたプログラマには簡単かもですが、私には難しかった。

 

2.Chainer 愛憎

 言われている通り、Chainer はコードが書きやすい。tf と比べて楽。

 しかし、最近のアップデートで Chainer 2.0 となり、一部で互換性が失われたですよ。Chainer v1.14 で動くコードが v2.0 で動かなかったりする。困ったものだ。

 GPU の使い方もよくわからない。今は GPU を使えておらず、全部 CPU で処理している。CPU は i3-7100 や i5-7600K を使っているのだけど、遅い、遅い。

 

 この点、 Tensorflow は良い。明示的に 「GPU を使ってください」 と書かなくても、勝手に GPU を使ってくれる。

 ありがたやありがたや。

 CPU only だと数分かかるタスクが、モノの10秒で終わってしまうよ (^^)

 

 Tensorflow もアップデートを繰り返しているけど、互換性が切れたメソッドには、

  「こういうアップデートがありました。このように書いてください」

 ってエラーメッセージを返してくれる。

 Chainer も同じこと、できないのかなぁ。 

 

 

 Deep learning の勉強、歩みはのろいけど、まぁ順調かな。

 

 この先やるべきことはいろいろある。どこからどう手を付けていっていいのか。

 自分に技術力がないことはよく理解した。

 そろそろ専門家の人と共同研究にしたい。

 あいにくそのような知り合いがいないのだけど、どうやって探すものなんだろう。

  (あー、今年の人工知能学会に行っときゃよかった!! PyconJP も行きたかったけど、開催日を知ったのはごく最近。すでに定員いっぱいになっちゃってたし・・・)

 

 他に自然言語処理もやりたいのだけれど、これはさらに難しそう。ホント専門家にお任せしたいな・・・

 

 これを自分の専門にできればそれでいいのだけど、そういうポストあるのか。

 でも機械学習の基礎はないから、そういうポストに潜り込むのも難しそうだし。

 ぐだぐだ。

deep learning でよく使うimport文を保存しておく(python)

スクリプト・コピペ用

def main():

    import chainer, cv2, dicom, glob, os, pickle, shutil, sys, time
    from chainer import cuda, Function, gradient_check, \

                                    optimizers, serializers, utils, Variable

    from PIL import Image

    import chainer.functions as F

    import chainer.links as L

    import matplotlib.pyplot as plt

    import numpy as np

    import tensorflow as tf

if __name__ == '__main__':

    main()

 

対話的

import chainer, cv2, dicom, glob, os, pickle, shutil, sys, time

from chainer import cuda, Function, gradient_check

from chainer import optimizers, serializers, utils, Variable

from PIL import Image

import chainer.functions as F

import chainer.links as L

import matplotlib.pyplot as plt

import numpy as np

import tensorflow as tf 

 

dicom を匿名化 (python, pydicom, pycrypto)

python で、pydicom と pycrypto を使って dicom ファイルを匿名化・暗号化します。

 

 

 

暗号化については、pycrypto というライブラリを使い、AES 方式で暗号化する方法がネットに上がっておりましたので、それを利用しました。

 

pycrypto の使い方は

暗号化ライブラリ pycrypto · kamatari

を参考にしました。

 

コードを使う際は、必ず 'secret_key' のところを変更(ThisIsTopSecret! を別の単語に!)して使ってください。この部分が、暗号解読のパスワードになるためです。

(パスワードの文字数は、16、24、32文字のいずれかだそうです。当然長いほうがより secure ですので、できれば長いパスワードをご利用ください)

 

個人情報の大部分を 'no data' で置き換えますが、後で再使用が必要かもしれない

 ID

 age

 性別

は後で確認できるよう、暗号化としています。

 

pycrypto では、暗号化する対象は 半角英数字で、16の倍数の文字数 である必要があるそうです。

下記スクリプトは、

 ID が8桁

 age が2桁

 性別 が1桁

と想定して、文字数を調整しています。桁数がちばう場合には、適宜調整してください。

 

# -*- coding: utf-8 -*-

'''カレントディレクトリ内にある dicom ファイルを Encrypt します

実装かっこ悪くてすみません'''

import os, time, dicom

from Crypto.Cipher import AES

start = time.time()

print('started : ' + time.ctime())

secret_key = 'ThisIsTopSecret!'

#password は半角16,24,32文字

def main():

    print('__encryption started!!__')

    for file_name in os.listdir('.'):

        root, ext = os.path.splitext(file_name)

        if ext == '.dcm':

            ds = dicom.read_file(file_name)

            cryp = AES.new(secret_key)

            ds.PatientAddress = 'no data'

            ds.PatientBirthDate = 'no data'

            ds.PatientBirthName = 'no data'

            ds.PatientName = 'no data'

            ds.PatientSize = 0

            ds.PatientWeight = 0

            ds.PatientMohterBirthName = 'no data'

            ds.PatientTelephoneNumbers = 'no data'

            ds.CountryofResidence = 'no data'

            ds.PatientAge = cryp.encrypt(

              str(ds.PatientAge) + '___4___8__12__'

              )

            ds.PatientID = cryp.encrypt(

              str(ds.PatientID) + '___4___8'

              )

            ds.PatientSex = cryp.encrypt(

              str(ds.PatientSex) + '___4___8__12___'

              )

            ds.save_as(root + '_encrypted.dcm')

            print(

                    '__' + file_name + ' was encrypted as ' +

                    root + '_encrypted.dcm!!__'

                   )

    print('__finished!!__')

    elapsed_time = time.time() - start

    print('finished : ' + time.ctime())

    print('elapsed time : {0} sec'.format(elapsed_time))


if __name__ == '__main__':
    main()

'''こちらを参考にさせていただきました
https://kamatari.github.io/2016/04/23/what-is-pycrypto/'''

 

 

こちらは変更バージョンです。

上記スクリプトで 'no data' で置き換えていたところに 無意味な半角英数字 を挿入し、暗号化しているように見せかけたものです。

 

暗号化の解除に、多少 余計に時間がかかるかもしれないと思い、修正しました。

 

# -*- coding: utf-8 -*-

import os, time, dicom, random

from Crypto.Cipher import AES

 

start = time.time()

print('started : ' + time.ctime())

 

secret_key = 'ThisIsTopSecret!'

#password は半角16,24,32文字

 

def main():

    print('__encryption started!!__')

    for file_name in os.listdir('.'):

        root, ext = os.path.splitext(file_name)

        if ext == '.dcm':

            ds = dicom.read_file(file_name)

 

            cryp = AES.new(secret_key)


            SixteenInt = random.randint(

                1000000000000000,

                9999999999999999

                )

 

            ds.PatientAddress = cryp.encrypt(str(SixteenInt))

            ds.PatientBirthDate = cryp.encrypt(str(SixteenInt))

            ds.PatientBirthName = cryp.encrypt(str(SixteenInt))

            ds.PatientName = cryp.encrypt(str(SixteenInt))

            ds.PatientSize = 0

            ds.PatientWeight = 0

            ds.PatientMohterBirthName = cryp.encrypt(str(SixteenInt))

            ds.PatientTelephoneNumbers = cryp.encrypt(str(SixteenInt))

            ds.CountryofResidence = cryp.encrypt(str(SixteenInt))

 

            ds.PatientAge = cryp.encrypt(

              str(ds.PatientAge) + '___4___8__12'
              )

            ds.PatientID = cryp.encrypt(

              str(ds.PatientID) + '___4___8_'

              )

            ds.PatientSex = cryp.encrypt(

              str(ds.PatientSex) + '___4___8__12___'

              )

 

            ds.save_as(root + '_encrypted.dcm')

 

            print(

                    '__' + file_name + ' was encrypted as ' +

                    root + '_encrypted.dcm!!__'

                   )

 

    print('__finished!!__')

    elapsed_time = time.time() - start

    print('finished : ' + time.ctime())

    print('elapsed time : {0} sec'.format(elapsed_time))

 


if __name__ == '__main__':

    main()

 

'''こちらを参考にさせていただきました
https://kamatari.github.io/2016/04/23/what-is-pycrypto/'''

 

ディープラーニング準備 Ubuntu14 インストールから cuda 導入トラブルシュート

 導入トラブルとトラブルシュート

1.Ubuntu は DVD ではなく、USB からインストールする。

 DVD player が対応していないと、drubのインストールに失敗する(起動できなくなる!)ことがある。もし DVD でインストールを試して「致命的なエラー」が出たら、USB からを試してみて。

Ubuntu 14.04.3をUEFIモードでインストールした時に詰まった - あお日記

 

2.クリーンインストール(再インストール)時、/home はフォーマット必須。

  なお、

  SSD が /

  HDD が /home と設定している時。そのほかの場合は分からないけど。

 フォーマットしないと一部ふるい設定が残ってしまう。

 

3.ストレージは 2TB まで!

 それ以上だと Ubuntu 14 が認識できず、トラブるみたい。

 パーティション切って 2TB 以下にすれば大丈夫かもしれないけど、試してないので。

 

4.cudaの依存パッケージを事前にインストールする。

 Ubuntu14 クリーンインストール後、すぐには cuda 入らなかった。何かパッケージに依存してるっぽい。

 でも何が必要なのかは、確認できなかった。

 afni / freesurfer / FSL インストール後なら問題なく入った。

 医用画像解析にこれらは便利だし、上記インストール後の方が無難 

Ubuntu 14.04初期設定 - 医用画像で Deep Neural Network

 

5.cuda は、cuda のページからダウンロードすること

 cuda は NVIDIA のグラボのドライバーなので、グラボのドライバーをインストールすれば、 cuda が使えると思うかもしれない。

 少なくとも私はそう思った。ので NVIDIA-driver のサイトからもDLしてみた。でもインストール後、cuda は 5.5 (2017年6月現在、最新は8.0)であった。敢えて古いのを使う必要はないであろう・・・

 ディープラーニングに使うには、基本新しい cuda の方が良いだろうから(最新の8.0に未対応のライブラリもある。事前確認が必要)。

 

6.CPU、RAMのオーバークロックは切っておく

 一度、オーバークロックに関係ありそうなエラーが出た。

 

7.cuda のインストールは CUI

 こちらを参考にしました。

Xubuntu 14.04にNVIDIAの最新ドライバーをインストールする方法(Xubuntuをテキストモードで起動させる方法)

  

一節には、blacklitでnouveauを止めないとインストールに失敗するという話もあるが、

はじめての深層学習(ディープラーニング)プログラミング:書籍案内|技術評論社

私の経験では、それは不要。

  

8.cudnn のインストール前に、ライブラリが対応しているか確認すること。

 最新版を入れたら tensorflow が動かなかったので。

 だだし、cudnn のアンインストールと再インストールは簡単なので、最新版をとりあえず入れてもそんなに悪くはないかも。

 

9.Anaconda のインストールで、$ sudo bash Anaconda...と管理者でインストールするとハマる。

 root 権限でインストールされ、自分のアカウントで使えなくなる。

sudo su

すれば使えるだろうけど、セキュリティ的に。

また、chmod chgrp などはできるのだけど、その後もエラーが出るので、再インストールするのが無難だと思う。

 

アンインストールは、ネット検索で正式な方法が見つからなかったので

sudo rm -rf ~/Anaconda3 ~/.conda

とした。

これが正しい方法なのか分からない。

ご存じの方はコメントください。

 

chmod した場合のエラーだけれど、

conda create -n tensorflow python=3.5 anaconda

で permission エラーが出ることがあった。

仮想が使えないのは痛い。

 

10.Teamviewer

Ubuntu 14 だと、

sudo dpkg -i filename

でインストールできない。

この後に

sudo apt-get update -f 

と打つ必要あり。

How do I install TeamViewer on my Linux distribution?

 

11.R言語と RStudio

貧乏科学者御用達(?)の統計ソフト・プログラミング言語 R。

RStudio のインストールには、ベースとなる「R」が必要。

自分の場合は afni をインストールする際に、一緒にインストールされる。

afni でインストールされているにも関わらず、

sudo apt-get install r-base 

をするとエラーが出るので、これはやらないこと。

 

Ubuntu14.04初期設定

またトラブって10回くらい再インストールした(してる)ので、自分のためのコピペまとめ。

つらいぜ・・・ 

いつも

Ubuntu 14.04 LTSをインストールした直後に行う設定 & インストールするソフト

を参考にしてたのだけど、

その中でも自分がいつも使うものを pick up にて modify 

 

何はなくとも

google-chrome-stable

をインストール。

 

ソフトウェアセンターからインストールする

gufw
clamtk
psensor
unity tweak tool

 

以下、ターミナルにコピペ

ドラッグアンドドロップでOK

# 最初

sudo ls

# で、sudo権限を承認しておくと楽。

 

# アップデート

sudo apt-get -y update && sudo apt-get -y upgrade

 

# スクロールバーを元に戻す
gsettings set com.canonical.desktop.interface scrollbar-mode normal

# フォルダーを英語表記に戻す
env LANGUAGE=C LC_MESSAGES=C xdg-user-dirs-gtk-update

# ゲストセッションを無効化する 
sudo sh -c 'printf "[SeatDefaults]\nallow-guest=false\n" >/usr/share/lightdm/lightdm.conf.d/50-no-guest.conf'

# 日本語リポジトリの追加
wget -q https://www.ubuntulinux.jp/ubuntu-ja-archive-keyring.gpg -O- | sudo apt-key add -
wget -q https://www.ubuntulinux.jp/ubuntu-jp-ppa-keyring.gpg -O- | sudo apt-key add -
sudo wget https://www.ubuntulinux.jp/sources.list.d/trusty.list -O /etc/apt/sources.list.d/ubuntu-ja.list
sudo apt-get update
sudo apt-get install ubuntu-defaults-ja

# fcitxパッケージのインストール(これは日本語リポジトリでインストールされるみたいなので、しなくて良いのかも。)
sudo apt-get install fcitx fcitx-mozc fcitx-libs-qt5 fcitx-frontend-qt5

# ここでfcitxの設定。
# dash-fcitxセットアップヘルパー で、fcitxを通常使う日本語入力システムに
# 「ok」をクリックするだけ
# システム設定を開き、言語サポートをインストー
# dash-fcitx設定 で、入力メソッドのオンオフ に、お好みの設定を追加。

 

# exfat利用

sudo apt-add-repository ppa:relan/exfat

sudo apt-get update

# ここで公開鍵を利用できないエラーが出るので、修正

sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys #ここに公開鍵番号#

sudo apt-get update

sudo apt-get install exfat-fuse exfat-utils

 

ホームページからそれぞれダウンロード

afni, freesurfer, FSL,

  http://pmonty.hatenablog.com/entry/2017/03/06/160848

 

 

cuda

cudnn

 

Rstudio

git

Anaconda

 tensorflow

 chainer

atom

 

tf のモデル (GoogLe net など)のダウンロード元

https://github.com/tensorflow/models 

 

python で再帰的にファイルを作成してみるぞ。

 

カレントディレクトリを確認。

import os

os.path.abspath('.')

os.listdir()

# bash で言うたら pwd, ls 

 

作成

直下の全てのディレクトリに、同一名のファイル作成。

import os

 

for i in os.listdir()

    with open(i + '/test.txt', 'w')

# test.txt ファイルが作成される。

 

関係ないけど、bash でファイルを作成と言えば

touch foo.txt

なんか意外と shell 本で取り上げられてない気がする。 

 

 

直下の全てのディレクトリに、同一名のディレクトリ作成。 

import os

 

for i in os.listdir('.')

    os.mkdir(i + '/test') 

# test ディレクトリが作成される。

 

ファイルの名称変更。

直下の全てのディレクトリ内にある全てのファイル名を

ディレクトリ名 + ファイル名に。

# すいません、うまくいかなかったんで、諦めて

flexrenamer (Windowsの無料ソフト)

# というソフトを使いました。

# 速いし超便利なソフトです。オススメ

 

 

今のところ、cmd や bash よりも使いやすいなり。

Python 便利 (^^)

「めんどうなことはpythonにやらせよう」と言う本が出るとか、出たとか聞くけど。

その気持ち、よく分かる。

 

作ってみた CNN があまりに遅く、「ハイパフォーマンス Python 」を読み始めました。メモリとかキャッシュとか、フロントサイドパス、バックサイドパスとか、よく分からない用語がたくさん。たまらんです。楽しい。そのうち、もっと基本な言語も勉強したい。Java なのか、C# なのか分からんけど。

 

Z270 とかのチップセットと X99 とかとの違いに メモリチャンネル、PCIeレーン数とかがあって、複雑なプログラムだと、そういうことが効いてくるんだろうなぁ・・・

今は Z170/Z270 のシステムを使っているけど、将来は X99 に移行したいな。

 

今は GPGPU で、SLI していないけど、将来したいけど。

Z170/270だと PCIe レーンが max 20 なので、SLI だと、一つの GPU あたり 3.0 x 8 しか使えないのかな。X99 だと 40 レーン。30 x 16 も 2 レーン確保できると思われ。そういうことも速さに効いてくるんだろうなぁ・・・ i7-6700K と比べて i7-6800K は速いと言うけど、それって CPU 性能だけではなく、そのあたりも効いてるのだろうと。

まっ、まだ今は、Python の最適化の勉強の方が先です!

pydicom の基本的な使い方

DICOM ファイルを python で扱いたいとき、まず触るのが pydicom でしょう。

科学技術分野に強いプログラミング言語python で dicom を自由に扱えるようになれば、医用画像の研究にとても便利! もちろんディープラーニングにも。

しかし日本語ドキュメントが少ないのが残念なところ。

とりあえず、いくつかコードを試してみます。

 

Python で DICOM を扱うのは、情報が少ないですが、

学習できるページ:

https://pyscience.wordpress.com/2014/09/08/dicom-in-python-importing-medical-image-data-into-numpy-with-pydicom-and-vtk/ 

http://qiita.com/fukuit/items/ed163f9b566baf3a6c3f

 

元のユーザーガイドはこちらです(英語)。

Pydicom User Guide — pydicom 1.0a documentation

一通りのコマンドを使ってみます。

 

python 3.6 (Anaconda) + pydicom 0.9.9 にて動作確認。

・・・・・・・・・・・・・・・・・・・・・・・・・・・

 

 

pydicom をインストールする。

PIP を使えば簡単。

bash

$ bash

pip install pydicom

 

pydicom のバージョンを確認する。

PIP にて確認。

bash

 $ bash

pip freeze

 

# answer

alabaster==0.7.9

anaconda-client==1.6.0

anaconda-navigator==1.5

...

pydicom==0.9.9

...

xlrd==1.0.0

XlsxWriter==0.9.6

xlwt==1.2.0 

 

 

 

pydicom をインポートする

# 以下、python

 

>>> python

import dicom #0.9.9までの対応

import pydicom as dicom #1.0以降への対応 

 

# 互換性を維持するため、呼び出し時のメソッドを、pydicom から dicom に変更。

 

# よく使うので、自分はついでに

import sys, os, time, random, dicom, pylab, cv2

import numpy as np

import tensorflow as tf

import matplotlib.pyplot as plt

from PIL import Image

# あたりまで一気にインポートしてしまう。

# コピペ。

 

DICOM 画像を読み込む

 

dicom.read_file() を使う

>>> python

ds = dicom.read_file("IM0.dcm")  # 0.9.9

 

# version >= 1.0a で、メソッドを変更しておかない場合は

ds = pydicom.read_file("IM0.dcm") # >= 1.0a

# dicom.read の代わりに pydicom.read と書く。

 

 

 

 

DICOM ヘッダーを表示する

 

>>> python

ds

 

# answer

(0008, 0005) Specific Character Set CS: 'ISO_IR 100'
(0008, 0008) Image Type CS: ['DERIVED', 'SECONDARY', 'AXIAL', 'MPR THICK', '', '', 'PARALLEL']
(0008, 0012) Instance Creation Date DA: '20171201'
(0008, 0013) Instance Creation Time TM: '105041.192537'
(0008, 0016) SOP Class UID UI: CT Image Storage

...

(0008, 0060) Modality CS: 'CT'

....

 

 

 

 

特定の DICOM ヘッダーを表示する

 

>>> python

ds.Modality

 

# answer

CT

 

 

 

ヘッダーを指定するメソッド( DICOM タグ)を確認する

 

>>> python

ds.dir()

 

# answer

['AccessionNumber', 'AcquisitionDate', 'AcquisitionNumber', 'AcquisitionTime', 'BitsAllocated', 'BitsStored', 'ClinicalTrialProtocolID', 'ClinicalTrialProtocolName', 'ClinicalTrialSiteID', 'ClinicalTrialSiteName', 'ClinicalTrialSponsorName', 'ClinicalTrialSubjectID', 'ClinicalTrialTimePointID', 'Columns', 'ContentDate', 'ContentTime',

(中略)

, 'PatientPosition', 'PatientSex', 'PhotometricInterpretation', 'PixelData', 'PixelRepresentation', 'PixelSpacing', 'PositionReferenceIndicator', 'PresentationLUTShape', 'ProcedureCodeSequence', 'ProtocolName', 'ReferringPhysicianName', 'RequestAttributesSequence', 'RequestedProcedureDescription', 'RescaleIntercept', 'RescaleSlope', 'Rows', 'SOPClassUID', 'SOPInstanceUID', 'SamplesPerPixel', 'SeriesDate', 'SeriesDescription', 'SeriesInstanceUID', 'SeriesNumber', 'SeriesTime', 'SliceThickness', 'SpecificCharacterSet', 'StationName', 'StudyDate', 'StudyDescription', 'StudyID', 'StudyInstanceUID', 'StudyTime', 'WindowCenter', 'WindowCenterWidthExplanation', 'WindowWidth'] 

 

 

 

特定の DICOM タグがあるかどうかを確認する

>>> python

"PatientsName" in ds

# answer

True

 

"Patients\ Name" in ds 

# answer

False

 

 

"""Patients Name""" in ds 

# answer

False

 

 

 

 

"pat" の入っている DICOM タグだけを grep (検索)したい

 

>>> python

ds.dir("pat")

 

# answer
 

['ImageOrientationPatient', 'ImagePositionPatient', 'IssuerOfPatientID', 'PatientAge', 'PatientBirthDate', 'PatientID', 'PatientIdentityRemoved', 'PatientName', 'PatientPosition', 'PatientSex']

 

 

 

特定の DICOM タグを削除する # 挙動は未確認

>>> python

del ds[0x10,0x1000]

 

# OR

 

tag = ds.data_element("OtherPatientIDs").tag
del ds[tag]

 

 

名前を匿名化して、別名保存する

>>> python

ds.PatientsName = 'Anonymus'

ds.save_as('anonymized.dcm')

 

 

ピクセルデータを取り出したい

幾つかの方法がある。

一列でデータを取る。

  普通に DL 目的に使うならこちらで良いか。

# MRIデータ

>>> python

pixel_bytes = ds.PixelData

pixel_bytes

 

 

# answer

\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00

\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00

\x00\x00\x00\x00\x00\x00 ....

 

# CT データ 。

 

>>>python

CT_pixel_bytes = ds.PixelData

CT_pixel_bytes

 

# answer

'x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\

#中略

0\x93\x00\x8b\x00}\x00V\x00F\x008\x007\x00<\x00B\x00@\x00@\

x000\x00;\x005\x001\x00=\x00,\x00(\x00*\x00$\x00,\x00\x004\x00/\

x00G\x00^\x00Z\x00T\x00^\x00\x00R\x00N\x00G\x00F\x00?\

x00:\x003\x00-\x00:\x003\x00=\

#中略

\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

### CT では x00^ とか、x00Z とか、多彩な数字が出てきました (^_^;)

### x00 が マイナス1000 でしょうね。

### わからん・・・

 

array, 2次元でデータを取る。  

  jpg とかの CNN と、互換性を気にするならこちら。

>>> python
pix = ds.pixel_array # NumPy ライブラリが必要とのこと

pix 

 

 

# answer

array([[0, 0, 0, ..., 0, 0, 0],
          [0, 0, 0, ..., 0, 0, 0],
          [0, 0, 0, ..., 0, 0, 0],
          ...,
          [0, 0, 0, ..., 0, 0, 0],
          [0, 0, 0, ..., 0, 0, 0],
          [0, 0, 0, ..., 0, 0, 0]], dtype=int16)

### int16 16ビット整数

### -2 **15 から 2**15 - 1 の値をとる。

### -32768 ~ 32767

### ムムム、バックグラウンドは-1000HU のはずなのに、0になっとる。。。 

 

 

 

 

 

画像を表示させたい

matplotlib を使う場合。

 

>>> python

import matplotlib.pyplot as plt

import pylab

ds = dicom.read_file("IM0.dcm")

im = ds.pixel_array

plt.imshow(im, cmap=pylab.cm.bone)

plt.show() 

 

ちなみに、普通に

>>> python

import matplotlib.pyplot as plt

import pylab

ds = dicom.read_file("IM0.dcm")

im = ds.pixel_array

plt.imshow(im) #ここが違う

plt.show()

普通に plt.imshow(im) とすると、なぜかカラー画像になっちゃう。

 

Numpy ndarray 経由で tf に数値データを渡す。

import numpy as np

import tensorflow as tf

import os, dicom

os.listdir()

ds = dicom.read_file('filetfname')

im = ds.pixel_array

im_float = im.astype(np.float32) # これはしなくても良い

a = tf.Variable(im_float)

sess = tf.Session 

sess.run(tf.global_variables_initializer())

sess.run(a) 

 

ついでに np.ndarray データを一列にする。

import numpy as np

import tensorflow as tf

import os, dicom

os.listdir()

ds = dicom.read_file('filetfname')

im = ds.pixel_array

imflat = [item for sublist in im for item in sublist]

# 呪文みたい・・・

これで一列表記になる。

普通に imflat = ds.PixelData となると16進数でデータがとられて、データ型は 'bytes' 直感的ではない。いったん im = ds.pixel_array とすると、データ型は 'numpy.ndarray', 数値は int16, その後の処理に続けやすそう。いや、自分はまだ何もできないですけど。。。

imflat_float = imflat.astype(np.float32)

とか、float への変換も簡単。メモリ消費は np の方が多そうなので、デキるお方は bytes で頑張った方が速そうですが!

 

こうして数値で頑張れという話もある一方、面倒なので

plt.savefig('filename.jpg' bbox_inches='tight')

で jpg にしてしまえと言う悪魔のささやきも。。。 

ひとまず、以上。

 

data を漬物(pickle)にする。

※ unpickle して NN に戻すところがうまくいきません。

 うまく言ったら update します。

 

 

ディープラーニングの前処理で、画像データは行列データに変換される。

自分の作成した CNN では、list になる。

 

どうも、この

画像データ → リスト化

部分に時間がかかっているので、この部分を速くしたい。

 

python のデータ保存形式に pickle というものがあるらしい。複数形は pickles, ピクルスすなわち漬物。このネーミングが面白い。

 

Anaconda には入っていた(というか、default で python に入っているっぽいけど)ので

ので、新たにインストールする必要はない。

まず

import pickle

 続いて

with open('保存したいファイル名', 'wb') as なんか適当な名前:

    pickle.dump(保存したいもの, なんか適当な名前)

みたいな形式。

 

ちなみにバージョンが4種類 (0-3) あるらしく、 python2.7 では version 3 は読み込めないらしい。Python 2.7 でも扱う場合には、version 2 までにとどめておいたほうが無難。

また、fix_imports=True を入れておくと、python2との互換性を保とうとするらしい。

 

なので、具体的には

with open('imagedata.pickle', 'wb') as f:

    pickle.dump(foo, f, protocol = 2, fix_imports=True) 

with open('imagelabel.pickle', 'wb') as f:

    pickle.dump(bar, f protocol = 2, fix_imports=True)

みたいに保存。

 

Python3 でしか使わないなら、Version3 で保存したほうが圧縮率が高い。

  Version3だと、データ容量は20分の1程度に減少。Version2のfix_imports=True だと、その15%増しくらいの容量でした。

 

読み込みは

with open('imagedata.pickle', 'rb') as f:

    pickle.load(f, fix_imports=True)

みたいな感じでしょうか。よくわかりません。

 

pickle 化してから再読込すると、作成した CNN が走らないので、目下この問題の修正中。

・・・っていうか、ネット上には多数の画像認識 CNN の記事が溢れてるけど、みんなデータ取り込みをどうしてるんだろうね。TensorFlow のみでは、まだ data augmentation に満足できないので(5度とか10度とか、微妙に回転させたい)、

 データを openCV に落として、

 また tensorflow variables に戻して、

みたいなことができるようになりたい。

でも tensorflow にそういう微妙な回転が実装されていないということは、回転させなくても診断能は変わらないのかな、謎。

 

12.1. pickle — Python オブジェクトの直列化 — Python 3.6.1 ドキュメント

11.1. pickle — Python オブジェクトの直列化 — Python 2.7.13 ドキュメント

pickleでオブジェクトをファイルに保存する - Qiita

tensorboard を開く。

bash

tensorboard --logdir=/tmp/tensorflow_log


 をタイプする。

コンソールに返信があれば

 

ブラウザで

http://localhost:0.0.0.0.6006

とタイプ。

localhost://0.0.0.0:6006 云々は、コンソールに返信があるので覚えておかなくて大丈夫。

 

tensorboard の終了は Ctrl + C。必ず終了すること!!

同時に2つの tensorboard は立ちあげられないみたい。なので、前の tensorboard を終了してないと、次に学習しても tensorboard が立ち上がらない。

 

いろいろ可視化するには、コードに仕込んでおかないといけないみたい。まだそこまではできていない。

CNNディープラーニング前処理 画像をDL用に処理する。

フォルダ内のすべてのファイル取得(python

import glob
glob.glob('*')

 

for FILENAME in glob.glob('*'):
    print(FILENAME)

 イマイチ違いがわかってない。

 2.は for loop を回してるので遅いのかな?

 

Bash

for dir in $(ls .);do echo $dir; done

 

再帰的にディレクトリ構造を得る

# -*- coding:utf-8 -*-

import os

def get_abspath_recursive(directory):

    for root, dirs, files in os.walk(directory):

        yield root

        for file in files:

            yield os.path.join(root, file)

 

for file in get_abspath_recursive('.'):

    print(file)

参考: http://qiita.com/suin/items/cdef17e447ceeff6e79d

 

 

画像の表示, python3

# -*- coding:utf-8 -*-

from PIL import Image

import matplotlib.pyplot as plt

im = Image.open("xxx.jpg")

plt.imshow(im)

plt.show() 

 

 

画像のリサイズ, python3

# -*- coding:utf-8 -*-

from PIL import Image

im = Image.open("xxx.jpg").resize(  (100.100) )

im.save("NEWFILENAME.jpg")

  ※トリミングではないので、画像が変形する。

 

 

 

あるフォルダ内のすべての ,jpg ファイルを、短辺で正方形に crop する。

 

 Cropされたファイルはカレントディレクトリに入る。(python3)

 

 

# -*- coding: utf-8 -*-

'''フォルダ内にある .jpg を短辺で正方形に crop
'''

import os
import cv2


def main():
    for file_name in os..listdir('.'):
        root, ext = os.path.splitext(file_name)

 

        if ext == '.jpg':
            img = cv2.imread(file_name)
            height, width, channels = img.shape

            if height == width:
                cv2.imwrite("cropped_" + file_name, img)
            elif height > width:
                Start = (height - width) // 2
                End   = Start + width
                clp     = img[Start:End, :]
                cv2.imwrite("cropped_" + file_name ,clp)
            else:
                Start = (width - height) // 2
                End   = Start + height
                clp    = img[:, Start:End]
                cv2.imwrite("cropped_" + file_name ,clp)

        else:

            pass

 
if __name__ == '__main__':
    main()

 参考: http://qiita.com/satoshicano/items/bba9594a1203e24e2a31

 

 

あるフォルダ内のすべての .jpg ファイルを、長辺で正方形に crop? する。

 Cropされたファイルはカレントディレクトリに入る。(python3)

 

# -*- coding: utf-8 -*-


'''フォルダ内にある .jpg を長辺で正方形に crop'''

 

import os
import cv2
import numpy as np

 

def main():

    for file_name in os.listdir('.'):

        root, ext = os.path.splitext(file_name)

        if ext == '.jpg':

            img = cv2.imread(file_name)

            height, width, channels = img.shape

            tmp = img[:, :] 

 

            if height > width:

                size = height

                limit = width
            else:

                size = width

                limit = height

 

            start = int( (size - limit) / 2)

            fin = int( (size + limit) / 2)

 

            new_img = cv2.resize(np.zeros( (1, 1, 3), np.uint8), (size, size) )

            if size == height:

                new_img[:, start:fin] = tmp

                cv2.imwrite("squared_" + file_name ,new_img)

            else:

                new_img[start:fin, :] = tmp

                cv2.imwrite("squared_" + file_name ,new_img)

        else:

            pass

 

if __name__ == '__main__':

    main()

 

カレントディレクトリの、すべての .jpg ファイルを rotate させるスクリプト(python3)

# -*- coding: utf-8 -*-
'''
フォルダ内にある .png, .jpeg, .jpg を rotate して保存する。
'''

import os

from PIL import Image

 

def main():

    for file_name in os.listdir('.'):

        root, ext = os.path.splitext(file_name)

 

        if ext == '.jpg':

            img = Image.open(file_name)

            for Degree in (-15, -12, -8, -4, -2, 0, 2, 4, 8, 12, 15):

# for Degree in (この中に、保存したい角度を入れる。)

                Rotate = img.rotate(Degree)

                Rotate.save("rot_" + str(Degree) + file_name)

 

 

        else:

            pass 

 

if __name__ == '__main__':

    main()

 

 カレントディレクトリのすべての .jpg ファイルを左右 flip するスクリプト

 

 # -*- coding: utf-8 -*-
'''
フォルダ内にある .jpg を flip して保存する。
'''

import os

from PIL import Image

 

def main():

    for file_name in os.listdir('.'):

        root, ext = os.path.splitext(file_name)

 

        if ext == u'.jpg':
            img = Image.open(file_name)
            tmp = img.transpose(Image.FLIP_LEFT_RIGHT)
            tmp.save("flipped_" + file_name)

        else:

            pass

 

if __name__ == '__main__':

    main()

 

カレントディレクトリの全ての .jpg ファイルで、画像の彩度・明度・コントラストを変更して画像枚数を増やす。

# -*- coding: utf-8 -*-
'''カレントディレクトリの .jpg の彩度、明度、コントラストを変更する'''

import os
from PIL import Image
from PIL import ImageEnhance

def main():

#彩度:saturation を変更して保存する。

    for file_name in os.listdir('.'):
        root, ext = os.path.splitext(file_name)

        if ext == u'.jpg':

            img = ImageEnhance.Color(Image.open(file_name))

            for i in (0.5, 1.5):

                tmp = img.enhance(i)

                j = str(i)

                tmp.save("_Sat_" + j + file_name)

            else:

                pass

 

#明度: brightness を変更して保存する

    for file_name in os.listdir('.'):

        root, ext = os.path.splitext(file_name)

        if ext == u'.jpg':

            img = ImageEnhance.Brightness(Image.open(file_name))

            for i in (0.5, 1.2):

                tmp = img.enhance(i)

                j = str(i)

                tmp.save("_Brt_" + j + file_name)

        else:

            pass

 

#コントラスト: contrast を変更して保存する

    for file_name in os.listdir('.'):

        root, ext = os.path.splitext(file_name)

        if ext == u'.jpg':

            img = ImageEnhance.Contrast(Image.open(file_name))

            for i in (0.5, 1.2):

                tmp = img.enhance(i)

                j = str(i)

                tmp.save("_Cnt_" + j + file_name)

        else:

            pass

 

if __name__ == '__main__':
    main()

 

#参考: https://kazutoyo.jp/archives/74