PythonMania

普段はロボットとAIを組み合わせて色々作ってます。Python関係以外も色々投稿していくと思います。

【画像生成】落書きから写真を生成?「gauGAN」を試してみる

f:id:mizuhiki0111:20190501103159j:plain


マウスを使って描いたイラストが、一瞬のうちにリアルな風景写真に変換される技術「gauGAN」が面白そうだったので試してみました。


gauGANは今年の3月に開催されたNVIDIA’s GPU Technology Conference(GTC)にて発表された技術です。



gauGANで検索するとよく出てくる、マウスで描いた部分が写真に変換されるGUIみたいなのは見つからなかった(まだ公開されてない?)
ので、今回は学習済のモデルを使って画像を生成するまでをやってみたいと思います。


githubにコードが上がっています。


github.com




環境

Windows10 64bit
Anaconda
Python : 3.7

①環境の構築

上記のgithubページからhauGANのコードを取得します

git clone https://github.com/NVlabs/SPADE.git

環境作成

conda create -n gauGAN


必要なライブラリのインストール

cd SPADE-master\SPADE-master
pip install -r requirements.txt

ここでエラーが出る場合には、環境に合わせて自分でPytorchをインストールします

conda install torch‑0.4.0‑cp37‑cp37m‑win_amd64.whl

※これでインストールした場合、後から「No Module Named~」のエラーが出ますが

その都度必要なライブラリをインストールしてください



②データセットの取得

※学習済のモデルを使用する場合には必要ないかもしれないです!


githubのREAD MEに沿って、必要なデータセットを準備します。


今回は以下からCOCO-Stuff Datasetというデータセットを取得しました。


github.com


このページから「train2017.zip」と「test2017.zip」をダウンロードし、解凍しておきます。


解凍したらtrain・test両方ともgauGANのSPADE-master\SPADE-master\datasetsフォルダに移動しておきます。





③the Synchronized-BatchNorm-PyTorchの取得


以下から取得します。

github.com


取得したフォルダ(Synchronized-BatchNorm-PyTorch-master)の中身一式(sync_batchnormとか)を


SPADE-master\SPADE-master\models\networkに移動しておきます。



④学習済モデルの取得

以下から取得し、解凍します。

drive.google.com



解凍したcheckpointsフォルダをSPADE-master\SPADE-masterに移動しておきます。



⑤学習済モデルを使って、画像を生成する

以下のようなコマンドで生成することができます

python test.py --name [type]_pretrained --dataset_mode [dataset] --dataroot [path_to_dataset]


今回の場合だと

python test.py --name coco_pretrained --dataset_mode coco --dataroot datasets/coco_stuff


このようなコマンドになります。


生成された画像はresultsフォルダに保存されます。

多少歪んでますが、ちゃんと生成で来てますね!



f:id:mizuhiki0111:20190501111913p:plainf:id:mizuhiki0111:20190501111922p:plain
f:id:mizuhiki0111:20190501111927p:plainf:id:mizuhiki0111:20190501111936p:plain
f:id:mizuhiki0111:20190501111919p:plainf:id:mizuhiki0111:20190501111929p:plain
f:id:mizuhiki0111:20190501111923p:plainf:id:mizuhiki0111:20190501111933p:plain

【Python】「DLL load faild : 指定されたプロシージャが見つかりません」エラーについて

f:id:mizuhiki0111:20190430173420j:plain

Anaconda上でtensorflow用の環境を作成し、作成した環境上でtensorflowをインストール、実行しようとしたところ


「DLL load faild : 指定されたプロシージャが見つかりません」


というエラーが発生した。


ネット上で解決方法を探してもいまいち分からなかったが、


Anacondaをインストールした時のPythonのバージョンと作成した環境のPythonのバージョンを統一することでエラーは表示されなくなった。


※Anaconda3-5.2.0はPython3.6.5なので、作成する仮想環境のバージョンもPython3.6.5で作成。



ただこれだと環境ごとにPythonのバージョンを切り替えることができなくなってしまうので根本的な解決にはなっていないですが


ひとまず動いたので備忘録として記事にしておきます。


こちらの解決方法が見つかったらまた改めて記事にしたいと思います。
(どなたか詳しい方がいらっしゃいましたら教えていただけると嬉しいです!)

【Python】ChainerCV + GPU環境を構築する

f:id:mizuhiki0111:20190430172704p:plain




環境

Windows10 64bit
Python : 3.6.5
chianercv : 0.12.0
CUDA : 9.0
cudnn : 7.2.1
VisualStudioCommunity2017(後述)
cupy:5.4.0




CUDAのインストール

developer.nvidia.com


上記サイトからCUDA ToolKitをダウンロードしてきてインストールします。


過去のバージョンについては画面下部の「Legacy Release」のところからダウンロードできます。



cudnnのインストール

developer.nvidia.com


上記サイトからCUDAのバージョンにあったcudnnをダウンロードしてきます。

※cudnnをダウンロードするにはNVIDIAのメンバーシップ(無料)への登録が必要です

ダウンロードしてきたzipファイルを解凍し、中身を以下の場所に移動させます。

cudnn64_7.dll →C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v9.0\bin\ にコピー

cudnn.h → C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v9.0\include にコピー

cudnn.lib → C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v9.0\lib\x64 にコピー



VisualStudioCommunity(コンパイラ)のセットアップ



docs.microsoft.com



VisiualStudioの最新版は2019ですが、2015のBuildToolsを使用する関係から

VisualStudio2017をインストールします


必要なのはVisualStudio2015のBuildToolsですが、現在公式のサイトからは入手できなくなっています。


ダウンロードしたexeファイルを起動し、インストーラが起動したら


C++ BuildToolsにチェックを入れ、画面右下に表示される

「デスクトップ用のVC++2015.3 v140~」と書かれた項目にチェックを入れてインストールします。




chainerCVのインストール

pip install chainercv

cupyのインストール

pip install cupy[f:id:mizuhiki0111:20190430172704p:plain][f:id:mizuhiki0111:20190430172704p:plain]

OpenCVで画像を読み込むと色が変わってしまう

OpenCVで画像を読み込んで表示した際に、画像の色が変わってしまうことがあります。




具体的には茶色の部分が合おうく表示されてしまします。



この画像が

f:id:mizuhiki0111:20190425113402j:plain




こんな感じになります



f:id:mizuhiki0111:20190425113359j:plain



これは色を表示する順番の違い(BGR(青緑赤)RGB(赤緑青)が原因のようです。



Pythonの画像処理ライブラリであるOpenCV(RGB)とPillow(BGR)の違いにより発生するみたいですが

僕の場合はOpenCVで読み込み・表示を行っても色が変わってしまう現象が起きました笑




この場合はnumpy配列に変換した後にcv2.cvtColor(img, cv2.COLOR_BGR2RGB)で変更すればOKです



img = "~/test.jpg"
img = cv2.imread(img)
img = np.asarray(img)  
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
plt.imshow(testImg)

GoogleのSpeech APIを使って音声を文字起こししてみる

f:id:mizuhiki0111:20190430175903p:plain




GoogleのSpeach APIを使えば 音声のテキスト変換が簡単にできるみたいだったので試してみました。


音声データ(mp3)を引数で指定して実行するとテキストファイルを生成することができるようにしてあります。



これを使えば会議の内容を録音→議事録作成なんかが効率よくできそうですね!







以下コードになります
(コードを実行するためには、あらかじめGoogle Speach APIの有効化・API Keyの取得まで済ませておく必要があります)


コマンドライン引数「--sound」で音声ファイル指定で実行できると思います。


import requests
import json
from pydub import AudioSegment
import base64
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--sound")
#parser.add_argument("--dir")
args = parser.parse_args()
bassdir = "/"
str_api_key = "API Keyを指定"
sound = AudioSegment.from_mp3(args.sound)
sound.export(bassdir + "result.wav", format="wav")
sound = AudioSegment.from_wav(bassdir + "result.wav")
sound = sound.set_channels(1)
sound.export(bassdir + "result.wav", format="wav")
speech_file = bassdir + "result.wav"
def stt():
    str_url = "https://speech.googleapis.com/v1/speech:recognize?key="
    str_headers = {'Content-Type': 'application/json; charset=utf-8'}
    url = str_url + str_api_key
    with open(speech_file, 'rb') as speech:
        speech_content = base64.b64encode(speech.read())
    str_json_data = {
          "config": {
          "encoding": "LINEAR16",
          "sampleRateHertz": 44100,
          "languageCode": "ja-JP",
          "enableWordTimeOffsets": False
          },
          "audio": {
          'content': speech_content.decode('UTF-8')
           }
         }
    with open(args.dir + "result.json", 'w') as f:
        json.dump(str_json_data, f)
    jd = json.dumps(str_json_data)
    print("begin request")
    s = requests.Session()
    r = requests.post(url, data=jd, headers=str_headers)
    print("status code : ", r.status_code)
    print("end request")
    if r.status_code == 200:
        parsed = json.loads(r.text)
        sst_result = parsed["results"][0]["alternatives"][0]["transcript"]
        sst_result = sst_result
        return sst_result
    else:
        return "error"
if __name__ == "__main__":
    result = stt()
    with open(bassdir + "/result.txt", mode='w') as f:
      f.write(str(result))

DjangoとChainerを使って画風変換アプリを作ってみた!

f:id:mizuhiki0111:20190430175940p:plain





PythonのWebフレームワークである「Django」の勉強のために画風変換Web
アプリ「HASUI MAKER」を作成してみたので記事に残しておきます。




http://mizuhiki0111.pythonanywhere.com/mizuhiki0111.pythonanywhere.com
https://ja.wikipedia.org/wiki/%E5%B7%9D%E7%80%AC%E5%B7%B4%E6%B0%B4




写真をアップロードすると、明治の浮世絵師である「川瀬巴水」の画風に変換してくれます。


ja.wikipedia.org



初めてのWebアプリ製作だったのでいろいろと雑なところはありますが、せっかく作ったので期間限定で公開しています笑



※アップロードする画像のサイズが大きいと変換に時間が掛かるので、小さめの画像で遊んでみてください!

【Python】Kerasで学習したモデルをアプリに組み込む際の注意点【DeepLearning】

f:id:mizuhiki0111:20190430180019p:plain



学習済のモデルをアプリに組み込んで使おうとしたときに以下のようなエラーが出ることがある。




Cannot interpret feed_dict key as Tensor


これはkerasがスレッドセーフではないために、読み込んだモデルが別のスレッドでは動作しないために発生するエラーである。


解決策として推論の度にモデルを呼び出すのではなく、

事前にモデルを読み込んでコンパイルしておく方法が良いらしい。




以下のようなコードで解決しました。


model = model_from_json(open("~/model.json", 'r').read())
model.load_weights("~/resnet50_model.h5")
model._make_predict_function()


【Python】kerasで学習したモデル・パラメータを読み込んで推論してみる【DeepLearning】

f:id:mizuhiki0111:20190430180019p:plain

アプリに組み込んだりする際に、いちいちモデルを記載して学習して~というのは負担が大きいので通常は学習後にモデル・パラメータを保存しておき、それらを読み込む形でアプリに組み込む



今回は以前ResNet50をfine-tuningしたものを読み込む形で推論を行う、ということをやってみた。





注意しなければいけない点として、予測を行う画像を1枚読み込んで判別結果を返す、というような場合には、画像データを3次元→4次元に変換してmodel.predictに渡してあげないとエラーが出る


以下コードです



import numpy as np
from PIL import Image
import os
from glob import glob
import cv2
from keras.utils import np_utils
from matplotlib import pyplot as plt
import pandas as pd
import tensorflow as tf
from keras.models import model_from_json

ScaleTo = 70

img = "~/4cd2a07dd.png"
# モデルの読み込み
model = model_from_json(open("~/resnet_model.json", 'r').read())

# 重みの読み込み
model.load_weights("~/resnet50_model.h5")

#model.summary()


testImg = cv2.resize(cv2.imread(img), (ScaleTo, ScaleTo))
testImg = np.asarray(testImg)  # Train images set

plt.imshow(testImg)
blurImg = cv2.GaussianBlur(testImg, (5, 5), 0)
plt.imshow(blurImg)
hsvImg = cv2.cvtColor(blurImg, cv2.COLOR_BGR2HSV)
plt.imshow(hsvImg)
lower_green = (25, 40, 50)
upper_green = (75, 255, 255)
mask = cv2.inRange(hsvImg, lower_green, upper_green)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (11, 11))
mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel)
plt.imshow(mask)
bMask = mask > 0
clear = np.zeros_like(testImg, np.uint8)  # Create empty image
clear[bMask] = testImg[bMask]
clearTestImg = clear
   # Apply boolean mask to the origin image
plt.imshow(clearTestImg)

clearTestImg = np.asarray(clearTestImg)

clearTestImg = clearTestImg / 255

clearTestImg.shape
clearTestImg = np.expand_dims(clearTestImg, axis=0)
pred = model.predict(clearTestImg)


#提出ファイルの作成
predNum = np.argmax(pred, axis=1)
predNum
#predStr = le.classes_[predNum]

#res = {'file': testId, 'species': predStr}
#res = pd.DataFrame(res)
#res.to_csv("res.csv", index=False)




【Python】Kerasで学習したモデルとパラメータの保存・読み込み方法 【DeepLearning】

f:id:mizuhiki0111:20190430180019p:plain



自分用にメモ




保存時

#モデルの保存
model_json_str =  model.to_json()
open(' model.json', 'w').write(model_json_str)

#パラメータの保存
model.save_weights(' model.h5');

読み込み時

#モデルの読み込み
model = model_from_json(open("~/model.json", 'r').read())

# 重みの読み込み
model.load_weights("~model.h5")

【Python】画像認識 - kerasでResNet50をfine-tuningしてみる 【DeepLearning】

f:id:mizuhiki0111:20190430180019p:plain

#必要なライブラリの読み込み
from sklearn.model_selection import train_test_split
import numpy as np
from PIL import Image
import os
from glob import glob
from sklearn.preprocessing import LabelEncoder
import cv2
from keras.utils import np_utils
from matplotlib import pyplot as plt
import pandas as pd



#画像のサイズ指定
ScaleTo = 70
seed = 7
n_categories = 12

#トレーニングデータの読み込み
data_dir ="../input/train"
path = "../input/train/*/*.png"
files = glob(path)

trainImg = []
trainLabel = []
j = 1
num = len(files)

#画像データをリストに格納
for img in files:
    print(str(j) + "/" + str(num) , end="\r")
    trainImg.append(cv2.resize(cv2.imread(img) ,(ScaleTo,ScaleTo)))
    #trainLabel.append(img.split("/")[-2])
    j += 1


#ラベルをリストに格納
for dir in os.listdir(data_dir):
    if dir == ".DS_Store":
        continue
    dir1 = data_dir + "/" + dir
    label = dir

    for file in os.listdir(dir1):
        if file != "Thumbs.db":

            trainLabel.append(label)


# kerasに渡すためにnumpy配列に変換。
image_list = np.asarray(trainImg)
label_list = pd.DataFrame(trainLabel)


clearTrainImg = []
examples = [];getEx = True

for img in image_list:
    #ぼかしを入れてノイズを除去
    blurImg = cv2.GaussianBlur(img ,(5,5),0)
    #RGBからHSVに変換
    hsvImg = cv2.cvtColor(blurImg , cv2.COLOR_BGR2HSV)
    #マスクを作成
    lower_green = (25,40,50)
    upper_green = (75,255,255)
    mask = cv2.inRange(hsvImg , lower_green ,upper_green)
    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(11,11))
    mask = cv2.morphologyEx(mask , cv2.MORPH_CLOSE,kernel)

    #ブールマスクの作成
    bMask = mask > 0

    #マスクの適用
    #空のイメージの作成
    clear = np.zeros_like(img , np.uint8)
    #オリジナル画像にブールマスクを適用
    clear[bMask] = img[bMask]

    clearTrainImg.append(clear)


for i in range(8):
    plt.subplot(2, 4, i + 1)
    plt.imshow(clearTrainImg[i])


clearTrainImg = np.asarray(clearTrainImg)
clearTrainImg.shape
# クラスの形式を変換
le = LabelEncoder()
le = le.fit(label_list)
label_list = le.transform(label_list)
label_list
label_list = np_utils.to_categorical(label_list)
label_list

X_train, X_test, y_train, y_test = train_test_split(clearTrainImg, label_list, test_size=0.33, random_state=0)



from keras.preprocessing.image import ImageDataGenerator
datagen = ImageDataGenerator(
        rotation_range=180,  # randomly rotate images in the range
        zoom_range = 0.1, # Randomly zoom image
        width_shift_range=0.1,  # randomly shift images horizontally
        height_shift_range=0.1,  # randomly shift images vertically
        horizontal_flip=True,  # randomly flip images horizontally
        vertical_flip=True  # randomly flip images vertically
    )
datagen.fit(X_train)











#モデル作成・学習
from keras.applications.resnet50 import ResNet50
from keras.models import Model
import tensorflow as tf
import keras
from tensorflow import keras
from keras.layers import Conv2D, MaxPooling2D,Input
from keras.layers import Dense, Dropout, Flatten, Activation,GlobalAveragePooling2D,Input
from keras.models import Sequential
from keras.callbacks import EarlyStopping, ReduceLROnPlateau, ModelCheckpoint
from keras.optimizers import Adam
from keras import optimizers


# ResNet50のロード。FC層は不要なので include_top=False
input_tensor = Input(shape=(ScaleTo, ScaleTo, 3))
resnet50 = ResNet50(include_top=False, weights='imagenet', input_tensor=input_tensor)

# FC層の作成
top_model = Sequential()
top_model.add(Flatten(input_shape=resnet50.output_shape[1:]))
top_model.add(Dense(256, activation='relu'))
top_model.add(Dropout(0.5))
top_model.add(Dense(nb_classes, activation='softmax'))

# ResNet50とFC層を結合してモデルを作成
resnet50_model = Model(input=resnet50.input, output=top_model(resnet50.output))

#ResNet50の一部の重みを固定
for layer in resnet50_model.layers[:100]:
    layer.trainable = False

# 多クラス分類を指定
resnet50_model.compile(loss='categorical_crossentropy',
          optimizer=optimizers.SGD(lr=1e-3, momentum=0.9),
          metrics=['accuracy'])
resnet50_model.summary()


#学習の実行
hist = resnet50_model.fit_generator(datagen.flow(X_train, y_train, batch_size=75),
                        epochs=35, validation_data=(X_test, y_test),
                        steps_per_epoch=X_train.shape[0])


                        steps_per_epoch=X_train.shape[0])


#モデルの評価
print(resnet50_model.evaluate(X_train, y_train)) #トレーニングの精度
print(resnet50_model.evaluate(X_test, y_test))  #テスト精度


#パラメータの保存
model.save_weights('../content/weights.h5')