2019/07/08
どうも、ディープなクラゲです。
「OpenVINO™ でゼロから学ぶディープラーニング推論」シリーズの4回目記事です。
このシリーズは、ディープラーニング概要、OpenVINO™ツールキット、Neural Compute Stick、RaspberryPiの使い方、Pythonプログラミングをゼロから徹底的に学び、成果としてディープラーニング推論アプリケーションが理解して作れるようになることを目指します。
今回は、Python基礎を学びます。
基礎から幅広く学ぶことも大事ですが、すぐに使わない項目を学んでも忘れてしまいます。
ここでは実践的に「OpenVINO™ でゼロから学ぶディープラーニング推論」で使うPythonに絞ってじっくりと説明してゆきます!ここで完全に理解しなくても、ディープラーニング推論を進める上で構文が出てきたときに「そういえばあったな」と思い出し、ここを見返せるようになれば良いかと思います。
Pythonはプログラミング言語の1つですが、特徴をあげると以下の3つです。
「スクリプト言語」とは、C言語やJAVAのようにコンパイルやビルドが不要で、プログラムを書いたら即実行が可能という意味です。
Pythonは、今回のようにディープラーニングや機械学習などに多く使われていますが、組込みやWebアプリケーションにも使われています。
構文のまとまりにカッコを使わず、インデント(字下げ)で表現するのが特徴的です
このシリーズで扱うPythonは主に以下の3つに分類できます
今回の記事では「Python基礎」を取り扱います。その他につきましては別の回で取り扱います。
なお、読み進めるにあたり、実際にコードを書いて実行しながら学習することを推奨します。
プログラミングのコードを記述するためのエディタは様々なものがありますが、ここでは最新のRaspberryPiに標準でインストールされている"Thonny"というGUIエディタを使います。
始めにコードを保存するための作業場所を作成しましょう。ユーザーのホームディレクトリの直下にworkspace
というフォルダを作成します。ファイルマネージャー(左上のフォルダアイコン)を開いて、右クリックで新規作成
>フォルダ
で簡単に作成できます。
次にThonnyを起動しますが、最初の起動方法にポイントがあります。
必ずターミナルからthonny
とコマンドを打って立ち上げて下さい。今回のPython基礎では特に問題は起きませんが、他の方法で立ち上げた場合は、OpenCVやInference Engineを使う際にエラーになります。
次のような画面が立ち上がります。
左上がコードを記述する領域、左下が結果を表示する領域、右側は変数の値を表示する領域です。右側の領域は今回は特に使わないので、狭くしたりクローズしたりしても構いません。
クラゲが使うメニューは5つだけです。
では、試しにコードを書いて実行してみましょう
print('hello, OpenVINO')
書いたらRun
ボタンを押します。そうすると保存先を求められるのでworkspace
を選んで、テキストボックスにtest.py
と記入して右下のOK
ボタンを押すかEnterキーを押すと実行されます。
以下のような黒太文字の結果表示がでれば成功です。
これ以降の進め方はNew
で新規作成しても良いですし、test.pyに追記や上書きでも良いです。
#
記号を書くことで、それ以降から行の終わりまでがコメント行になります。
コメント行とは、プログラム実行時に無視されるということです。主にプログラムに関する注釈を記述するために使用します。
#こんな感じで書きます
なお、複数行をコメントしたい場合は様々な方法がありますが、thonnyでは複数行を選択してからCtrl + #
キーを押すことで一気にコメント化とコメント解除が可能です。
文字列はシングルクォート '
もしくは ダブルクォート "
で囲みます。クラゲはシングルクォートで統一しようと思います。文字列を表示するには以下のような形でprint
を使います。
print('hello jellyfish')
変数の型宣言は不要です。整数も小数も文字列も同じように扱えます。代入は他のプログラミング言語同様 =
を用いて、左側に右側の値を代入します。
a = 2019b = 3.14c = 'jellyfish'print(a)print(b)print(c)
記号 +
, -
, *
, /
を用いれば四則演算可能です。
a = 100 + 200b = 24 - 8c = 10 * 3.14print(a)print(b)print(c)
以下の2行目のような書き方も良く使われます。自分自身に100を加え、結果的に600になります
a = 500a = a + 100print(a)
「ある変数に数値を足して、結果を同じ変数に代入する」という書き方は良く使われますので覚えておいてください。 a = a + 1
など 1
を足す場合は "インクリメント" と呼ばれます。
型を変更させる必要がある場合は、型変換を行う必要があります。
例えば、文字列から数値の小数に変更させる例です。float
を使います。
a = '3.14'b = 10 *print(b)
こちらは小数から整数に変更させる例です。int
を使います。
a = 3.14b = 10 *print(b)
どのプログラミング言語にも必ずあるif
文を使って条件分岐を行います。Pythonでの注意点はコロンとインデントです。コロンはif
の最後に書きます。インデントとは字下げのことで、以下のコードの場合はprint文の行です。TABキーを使ってスペースを空けます。
以下のコードは、変数time_of_sleeping
の値を見て、8より大きかった場合はprint文で表示を行い、それ以外の場合は何もせずプログラムを終了します。
time_of_sleeping = 10if time_of_sleeping > 8:print('よく寝ました')
ifと半角スペースの後に書かれているtime_of_sleeping > 8
は条件式と呼ばれる部分です。条件式が合っていれば、その下のインデントされたブロックが実行されます。
条件式には>
などの比較演算子が使われます。比較演算子は他に、<
<=
>=
==
!=
などがあります。
以下の例でtime_of_sleeping
の値を変更してみて、条件式が合っているとき・合っていないときで、どのブロックが実行されているのか確認してください。
time_of_sleeping = 6if time_of_sleeping < 8:print('しっかり睡眠を取りましょう!')print('クラゲからのアドバイスでした。')print('以上')
ブール型と呼ばれる変数がありif
とよく絡めて使われるので覚えておきましょう。ブール型はTrue
とFalse
のどちらかしか持てない変数のことです。
以下のコードでは、ブール変数sleepy
の値がTrue
のときにprint文を表示しています。
sleepy = Falseif sleepy == True:print('仮眠しよう!')
リストは他のプログラミングでいうところの配列にあたります
簡単に言うと、一つの値ではなく、一連の値を格納できる変数です。
代表的な使い方を見てゆきます
このように各要素をカンマで区切り、カッコ[ ]
内に記述します。
a =
リスト名[n]
でリストの要素にアクセスできます
Pythonでは要素番号は 0 から始まります。例えば n が 5 の場合は 6番目 の要素をアクセスすることになります。
a =b =print(b)
今回は、リストの中身を整数値にしましたが、小数や文字列など他の変数も扱うことも可能です。
Pythonの辞書は一言で言うと「キーワード付きのリスト」です。WEBプログラミングをやったことのある人であれば、JSON形式という用語を聞いたことがあるかもしれませんが、ほぼそれに近いです。
では、実際にコードを書いて実行してみてましょう。以下は果物の値段を変数に格納して参照する例です。リストで取り扱うことも可能ですが、辞書を使うことにより分かりやすくなります。
# 辞書の初期化a =# 辞書の参照b =# 表示print(b)
特徴的なのは、初期化のときに{ }
を使うことと、キーワード:値
というセットで格納することです。
リスト同様、キーワード
と値
は整数値以外も取り扱うことが可能です。ただし、キーワード
に関しては文字列を使うことが一般的です。
タプルとは要素を変更できないリストです。初期化時のカッコの形が( )
であり、リストや辞書と異なります。
a = (10, 20, 30, 40, 50, 60, 70, 80, 90, 100)b =print(b)
本シリーズでは主に、座標(X・Y)、画像の大きさ(幅・高さ)、色情報(青・緑・赤)などに使われます。
関数とは、入力値を受け取り、処理を行った後、出力値を結果として返すものです。
入力値を「引数(ひきすう)」、出力値を「戻り値」と呼びます。
具体例として、半径を引数とし、円周を求める処理を行い、円周値を戻り値として返す関数 circle
を作ってみましょう。
関数は def
で定義します。def 関数名(引数):
を記述した後にインデントを行い、処理をブロックに書きます。
円周の公式は 2 × π × r なので、変数 l
に対して l = 2 * 3.14 * r
で代入を行っています。return 戻り値
で結果を返すことができます。
l = 2 * 3.14 * rreturn l
関数の呼び出し側を加えます。以下は引数に 10
を入れて呼び出す例です。
l = 2 * 3.14 * rreturn lval =print(val)
関数の引数や戻り値は1つではなく複数でもOKです。
以下は、半径と円周率を引数として円周と円の面積を返す関数の例です。
l = 2 * pi * rs = pi * r * rreturn l, sval1, val2 =print(val1)print(val2)
これまでの関数の引数は、順番を一致させることにより受け渡しをしていました。(例えば上のコードの例では、r
に10
を渡し、pi
に3.14
を渡す)
関数呼び出し時に名前(キーワード)を付けることにより、順番に関係なく引数渡しを行うことができます。
l = 2 * pi * rs = pi * r * rreturn l, sval1, val2 =print(val1)print(val2)
順番は逆ですが、先ほどと同じ結果になったと思います。
このような引数の書き方を「キーワード引数」と呼びます。
PythonではOpenCVやNumPyなど様々な"モジュール"を読み込みます。
目的はモジュールの中にある複数の"関数"を活用するためです。
モジュールの読み込み方法は主に3通りです。time
モジュールのsleep
という関数を使用する場合を例に説明します。sleep
は引数に指定した秒だけプログラムを一時停止する関数です
一番分かりやすい読み込み方法です
関数を使う場合は モジュール名.関数名
で使います
import timeprint('start')timeprint('end')
as
を加えれば、モジュール名を別名にして取り扱うことができます
以下の例ではモジュール名をt
として取り扱っています
import time as tprint('start')tprint('end')
特定の関数しか使わない場合、この形式で書くことにより、関数使用時にモジュール名が不要になります
from time import sleepprint('start')print('end')
どの読み込み方法でも同じ結果です。
while True:
を使うことで、ブロックに対し、無限ループで実行させることができます。ifと同じようにブロックはインデントする必要があります。
以下は無限ループで変数num
の値を表示する例です。sleep
関数で1
を指定しているので1秒毎の表示です。ブロックの最後でnum
の値はインクリメントされているため、どんどん数値が増えてゆきます。
無限ループなのでプログラムは終了しません。ThonnyではStop
ボタンを押すことでプログラムを強制終了します。
import timenum = 0while True:print(num)timenum = num + 1
無限ループから抜け出すためのbreak
も良く使われます
以下はif
を使って、num
の値が5
以上になったらループを抜けてプログラム終了する例です。
import timenum = 0while True:print(num)timeif num >= 5:breaknum = num + 1
continue
はそれ以降のブロックをスキップしてブロック先頭に戻る処理を行います。
以下の先ほどのプログラムのbreak
をcontinue
に変更した例です。num
が5
以上になるとインクリメント部がスキップされて処理を繰り返します。
import timenum = 0while True:print(num)timeif num >= 5:continuenum = num + 1
forもwhile同様に繰り返し処理ですが、主に無限ループ以外の用途で使います。
0 ~ n-1 までの値を 変数 に代入してブロックを繰り返します。
例えば 5 回繰り返し処理を行いたいというときは、以下のようなコードになります。
for num in :print(num)
リストから順に値を取り出して変数に代入し、ブロックを繰り返します。
fruits =for x in fruits:print(x)
クラスと聞くと初心者の方は身構えてしまうと思いますが、ご安心ください。
クラスは、主に「クラスを自分で作成する場合」と「誰かが作ったクラスを使う場合」の2通りに分けることができます。前者はちょっと複雑で、「コンストラクタ」やら「継承」やら「self」やらややこしい用語やお作法も理解する必要がありますが、後者の場合は簡単です。関数に毛が生えたようなものというイメージでOKです。
ここでは具体的なコードは実行せずイメージで軽く説明します。
まず関数についての復習ですが、誰かが作った関数を使う場合は1ステップでいきなり使うことが出来ました。
以下はイメージですが、「クラゲに"kurage-san"という名前を付けて指定座標(100, 200)方向に泳がせる」という関数があったとします。
# 関数
一方のクラスは以下の2ステップを踏みます
# クラスa =a
クラゲが1匹だけで、泳ぐというアクションしかない場合は、クラスを使うメリットは全くありませんが、複数のクラゲを登場させ、それぞれが様々なアクション(眠る、食べる、光るなど)を複数行う場合は、クラスで扱ったほうが管理しやすいというのが何となく理解できるでしょうか?
この「登録」と「実行」を小難しい言葉で言い換えると以下のようになります
「インスタンス」とは何か? 良く例えられるのが「たい焼き」の例です。「クラス」がたい焼きを作る「たい焼き器」で、「インスタンス」は「たい焼き」そのもの。「たい焼き器」は1つしかありませんが、「たい焼き」はいくらでも作ることが可能です。今、これを聞いて理解できなくても全く問題ありません。聞き流してください。プログラムとしては、インスタンス名 = クラス名(引数)
という形で使うということだけ覚えておいてください。
次に「メソッド呼び出し」ですが、これは簡単です。
クラスは複数の関数を持っていて、その中の1つの関数を指定して呼び出しているということです。プログラムとしては、インスタンス名.メソッド名
という形で使います
なお、Pythonではクラス名の最初を大文字にするのが規則ですので、関数なのかクラスなのかはそれで判断できます。
以上、「Python基礎を学ぶ」でした。