TensorFlow GPU版をWindows 10にインストール

Window 10にTensorFlowをインストールして使っていたのだが、PyTorchで遊ぶ環境を作っていたら、 (たぶんPython 3.6にしたことが原因だけど)いつの間にかTensorFlowが動かなくなっていたので、再インストールした。 ここに、その手順を備忘録として残しておく。

なお、環境は次の通り。

1. Anaconda3-4.4.0 をインストール

Anacondaのアーカイブ にアクセスして、Anaconda3-4.4.0-Windows-x86_64.exe をダウンロード&インストール。

2. Python3.5 をインストール

Anaconda3-4.4.0により、Python 3.6がインストールされるが、Window 10では、Python 3.6とTensorFlowの相性が良くないらしい。 そのため、Python 3.5 をcondaでインストール。

> conda install python==3.5

3. TensorFlow 1.5をインストール

Build from source on Windowsによると、 CUDA 9とcuDNN 7の組合せの場合、TensorFlow GPU版はv1.5~1.12が使えるとある。 こちらを参考にCUDAとcuDNNのバージョンを確認したところ、 CUDA 9.0cuDNN 7.0.5だった。この組合せの場合は、tensorflow_gpu-1.5.0が無難そうである。 なので、pipでtensorflow_gpu-1.5.0をインストールする。 なお、condaを使うと必ずエラーになるという罠に何度もかかったので注意。pipを使う。

> pip install tensorflow-gpu==1.5

しかし、以下のようなエラーが出る場合がある。

...
AttributeError: '_NamespacePath' object has no attribute 'sort'

これはpipがエラーの原因なので、easy_installpipをインストールし直す。 pipが壊れたのは、condaでPython 3.5にしたのが原因と思われる。やはりconda、良さそうに見えて罠が多い。

> easy_install pip

これでpipが使えるようになったので、再度pipでtensorflow_gpu-1.5.0をインストールする。

> pip install tensorflow-gpu==1.5

次のようにDEPRECATIONが出るが、とりあえずOK。

...
`DEPRECATION: Uninstalling a distutils installed project (html5lib) has been deprecated and will be removed in a future version. This is due to the fact that uninstalling a distutils project will only partially uninstall the project.`
...

4. Numpy 1.14をインストール

Pythonを起動して、TensorFlowimportすると、またしてもエラーが出る。

>>> import tensorflow as tf
...
ImportError: cannot import name 'multiarray'

これはnumpyのエラーなのだが、こちらのIssueによると、 TensorFlow 1.6以上は、numpy 1.13.3以上である必要がある、とのこと。 TensorFlow 1.5だが、とりあえずcondanumpy 1.14を入れてみる。

> conda install numpy==1.14

これでOKのはず。

5. TensorFlowの動作確認

最終的には以下のように、これまでインストールしてきたモノとバージョンが確認できればOK。

> python
Python 3.5.0 |Anaconda 4.4.0 (64-bit)| (default, Dec  1 2015, 11:46:22) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import tensorflow as tf
>>> tf.__version__
'1.5.0'
>>>

参考文献

PythonでOCR

Netflixの字幕がダウンロードできると知ったので実行してみたが、 日本語字幕が画像だった※ため、PythonOCRにかけて文字列に変換した。結果は微妙。

※ 後でエピソード単位だと日本語字幕を文字列で取得できることに気付いた。。。作品単位だと画像になる模様。

Install

OSはWindows10。ORCには以下の2つが必要。

  1. pyorc-0.5.3
  2. tesseract-ocr-setup-3.05.02-20180621

1はpip。 2は、Tesseract at UB Mannheimから、 tesseract-ocr-setup-3.05.02-20180621.exeをダウンロードして実行。 最初3.02を使っていたが、精度が低かったため、3.05を選択。 4.00が出てるので、そちらの方がいいかも。 exe実行時、OCRにかける言語を選択するオプションでは日本語を選択すること。

Code

以下のコードを実行すると、字幕画像を文字列にしてファイルに出力してくれる。 OCRで解析したい画像字幕のフォルダはimg_dirに指定する。 文字列にした字幕ファイルもここに保存される。 なお、コードはgithubにも上げてます。

# coding: utf-8
from PIL import Image
import sys
import pyocr
import pyocr.builders
import os
from tqdm import trange

# Set Netflix subtitle image directory.
img_dir = '../data/planetes/PLANETES.S01E02.WEBRip.Netflix/'

# Get a tool.
tools = pyocr.get_available_tools()
if len(tools) == 0:
    print("No OCR tool found")
    sys.exit(1)
tool = tools[0]
print("Will use tool '%s'" % (tool.get_name()))

langs = tool.get_available_languages()
print("Available languages: %s" % ", ".join(langs))

# Image to string.
txts = []
img_names = [f for f in os.listdir(img_dir) if f.split('.')[-1].lower() in ('png')]
img_names = sorted(img_names)
print(img_names)
for i in trange(len(img_names), desc='img 2 str'):
    txt = tool.image_to_string(
        Image.open(img_dir+img_names[i]),
        lang='jpn',
        builder=pyocr.builders.TextBuilder()
    )
    print(txt)
    txts.append(txt)

# Save the subtitle.
subs = open(img_dir+'subs.txt', 'w')
subs.write('\n'.join(txts))
subs.close()

Result

複雑な漢字が苦手らしい。縁取りがあるからな気もする。 また、他の画像でも試したが、画像の大きさとも精度が相関している模様。

  • 画像
    f:id:Shoto:20190106181405p:plain

  • 文字列
    ステ一 ンヨノ建L ロ時に出た廃某 武物

  • 画像
    f:id:Shoto:20190106181419p:plain

  • 文字列
    これなんか
    かなり当たるようですよ

References

Inverse Trasnsformation of multihot matrix with DataFrame

When dealing with attributes in classification problem etc, there are some data saved in onehot or multihot matrix despite attributes are too many. Such data is too large to handle, I want to get only the target attributes and hold the data with smaller size. It is inverse transformation of multihot matrix and I processed it with DataFrame.

First prepare the data. Attributes (a - d) are 1 in each row.

lis = [
    ['row_0',1,0,0,0],
    ['row_1',1,1,0,0],
    ['row_2',0,0,0,1]
]
df = pd.DataFrame(lis, columns=['name', 'a', 'b', 'c', 'd'])
print(df)
    name  a  b  c  d
0  row_0  1  0  0  0
1  row_1  1  1  0  0
2  row_2  0  0  0  1

Get attributes in each row and insert them in one column. I am using a for statement, so I want to improve it.

lis = []
for i in range(len(df)):
    active_columns = df[df==1].ix[i].dropna().index.tolist()
    lis.append('_'.join(active_columns))
df['attr'] = lis
df = df.drop(['a', 'b', 'c', 'd'], axis=1)
print(df)
    name attr
0  row_0    a
1  row_1  a_b
2  row_2    d

Saving a image has no axis and no margin

When saving an image processed with matplotlib, the image axes and margins are not necessary. So I surveyed how to remove them and summarized them.

Code

from scipy.misc import imread
import matplotlib.pyplot as plt

img = imread('IMG_1382.JPG')
plt.imshow(img / 255.)
plt.axis('off')  # 1
plt.tick_params(labelbottom=False, labelleft=False, labelright=False, labeltop=False)  # 2
plt.savefig('IMG_1382_ex.JPG', bbox_inches='tight', pad_inches=0)  # 3

Points are the following.

  1. remove axes
  2. remove labels
  3. remove margin

Executable code is here. When $ test.py is input at terminal, the next image has no axis and no mergin is saved at the same directory.

f:id:Shoto:20180916010309j:plain

P.S. It works well on Windows, but remains small frame on Ubuntu. I don't know why.

References

GitHubリポジトリーの一部のフォルダーをダウンロードする

DeepLabV3+がTensorFlowで利用できるようになった。 とりあえず、DeepLabV3+関連のファイルだけ欲しいだが、GitHubにはそうゆう機能がないので、 Chrome拡張機能GitZipを使って、DeepLabV3+のフォルダーだけをダウンロードしてみた。

手順

  1. ChromeブラウザからGitZipをダウンロードしてインストール
  2. Chromeブラウザを再起動
  3. ダウンロードしたいリポジトリーのフォルダーの1つ上の階層を開く
  4. 対象フォルダーの余白部分をダブルクリック
  5. 左下の下向きの矢印をクリックしてフォルダーをダウンロード

実例

DeepLabV3+の場合、 research/deeplabフォルダーに入っているので、まずresearchフォルダーに移動する。 次にdeeplabフォルダーのコメントの右側の余白あたりをダブルクリックすると、 deeplabのフォルダーアイコンの左側にチェックが付く。 すると右下に下向きの矢印が現れるので、それをクリックするとダウンロードが開始する。

f:id:Shoto:20180505024253p:plain

参考文献

Download a single folder or directory from a GitHub repo

動画からの音声抽出と動画への音声結合

testpy.hatenablog.com

上記の記事で、動画を左右反転させて、新たな動画を生成した。 生成した動画には音声がないため、元の動画から音声を抽出して、結合してみた。

コード

# coding: utf-8
import sys
import cv2
import moviepy.editor as mp

class Test:
    def __init__(self):
        # Set video names.
        self.input_video = sys.argv[1]
        self.output_video = sys.argv[2]


    def main(self):
        self.set_audio()


    def set_audio(self):
        # Extract audio from input video.
        clip_input = mp.VideoFileClip(self.input_video).subclip()
        clip_input.audio.write_audiofile('audio.mp3')

        # Add audio to output video.
        clip_output = mp.VideoFileClip(self.output_video).subclip()
        clip_output.write_videofile(self.output_video.replace('.avi', '.mp4'), audio='audio.mp3')


if __name__ == "__main__":
    Test().main()

set_audio()が本体。前半2行で音声の抽出と保存、後半の2行で音声の結合を行っている。 結合する際、動画の拡張子がmp4じゃないとコーデックエラーが出る。 でも、mp4の方が容量が少ないので、それでいいかなと。

使い方

上記のコードをtest.pyで保存して、第一引数に入力動画名、第二引数に出力動画名(aviファイル)を指定する。

> python test.py input.MOV ouput.avi
[MoviePy] Writing audio in audio.mp3
100%|###################################################################################################################| 623/623 [00:00<00:00, 733.71it/s]
[MoviePy] Done.
[MoviePy] >>>> Building video output.mp4
[MoviePy] Writing video ouput.mp4
100%|####################################################################################################################| 846/846 [00:25<00:00, 33.65it/s]
[MoviePy] Done.
[MoviePy] >>>> Video ready: output.mp4

>

動画の生成と音声の結合を同時に実行

前回行った動画の生成と、今回行った音声の結合を同時に行ってみた。 音声を結合した動画がmp4なので、生成する動画もmp4(コーデックはMP4S)にしたのだが、警告が出て、どうも上手く音声付きの動画が生成されない。 この辺は後ほど対応したい。

OpenCV: FFMPEG: tag 0x5334504d/'MP4S' is not supported with codec id 13 and format 'mp4 / MP4 (MPEG-4 Part 14)'
OpenCV: FFMPEG: fallback to use tag 0x00000020/' ???'

同時に実行したコードを載せておく。 使い方は上に示したのと同じ。

# coding: utf-8
import sys
import cv2
import moviepy.editor as mp

class Test:
    def __init__(self):
        # Set video names.
        self.input_video = sys.argv[1]
        self.output_video = sys.argv[2]


    def main(self):
        self.make_video()
        self.set_audio()


    def make_video(self):
        # Get input video information.
        cap = cv2.VideoCapture(self.input_video)
        fps = int(cap.get(cv2.CAP_PROP_FPS))
        width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
        height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

        # Set output video infomation.
        fourcc = cv2.VideoWriter_fourcc(*'XVID')
        #fourcc = cv2.VideoWriter_fourcc(*'MP4S')
        vw = cv2.VideoWriter(self.output_video, fourcc, fps, (width, height))  # Set the above information.

        # Make the output video.
        print('Making a video...')
        while(True):
            ret, img = cap.read()
            if ret == True:
                img_flip = cv2.flip(img, 1)  # Flip horizontal
                vw.write(img_flip)  # Add frame
            else:
                break

        # Post processing.
        cap.release()
        cv2.destroyAllWindows()


    def set_audio(self):
        # Extract audio from input video.
        clip_input = mp.VideoFileClip(self.input_video).subclip()
        clip_input.audio.write_audiofile('audio.mp3')

        # Add audio to output video.
        clip_output = mp.VideoFileClip(self.output_video).subclip()
        clip_output.write_videofile(self.output_video.replace('.avi', '.mp4'), audio='audio.mp3')



if __name__ == "__main__":
    Test().main()

参考文献

OpenCVで動画を作成する

OpenCVで動画を作成できる。 動画を左右反転させて、新たな動画を作成してみた。

コード

# coding: utf-8
import sys
import cv2

class VideoMaker:
    def __init__(self):
        pass


    def main(self):
        # Set video names.
        input_video = sys.argv[1]
        output_video = input_video.replace('.MOV', '_flip.avi')

        # Get input video information.
        cap = cv2.VideoCapture(input_video)
        fps = int(cap.get(cv2.CAP_PROP_FPS))
        width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
        height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

        # Set output video infomation.
        fourcc = cv2.VideoWriter_fourcc(*'XVID')
        vw = cv2.VideoWriter(output_video, fourcc, fps, (width, height))  # Set the above information.

        # Make the output video.
        print('Making a video...')
        while(True):
            ret, img = cap.read()
            if ret == True:
                img_flip = cv2.flip(img, 1)  # Flip horizontal
                vw.write(img_flip)  # Add frame
            else:
                break

        # Post processing.
        cap.release()
        cv2.destroyAllWindows()


if __name__ == "__main__":
    VideoMaker().main()

解説

処理の大まかな流れは以下の通り。

  1. 入力動画の情報をゲット
  2. 出力動画の情報をセット
  3. 出力動画の作成・保存

FPSや画素数などを入出力で一致させている。 参考文献によると、コーデックはXVIDがおすすめとのこと。 MJPGX264も指定できるが、サイズが大きすぎたり小さすぎたりするらしい。 試してないけど。 vw.write(img_flip)で処理した画像を追加すれば、動画の作成と保存を同時に行ってくれる。 特に保存の必要はない。

使い方

video_maker.pyにコードを記載している。 コードと同じ場所に保存している動画(MOVファイル)を引数に指定すると、左右反転させた動画が作成される。

> python video_maker.py 2018_spring.MOV
Making a video...
>

参考文献