読者です 読者をやめる 読者になる 読者になる
自分のための備忘録的なブログです。

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


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

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

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

オブジェクト指向プログラミング(OOP)とは

記載されている年は基本的に登場年

強調されてるところとか見ると違和感があるかもしれないけど、私は DNN のために Python を学び初めた初心者。普通のプログラミング初心者が躓かないところで躓いてると思われ、そっとしておいてください。

 

 

 

オブジェクト指向プログラミング(Object oriented proglaming, OOPとは

 プログラムの保守性や再利用性を向上させる技術。オブジェクト指向プログラミング言語は (OOP language: OOPL) と呼ぶべきだが、ここでは OOPL も含め OOP と記載する。

  エドガー・ダイクストラ氏による「構造化プログラミング」(1967,goto 文を廃止し、プログラムの進行を巡行・分岐・繰り返しの3つに限定すること)を発展させたものとしても語られる。

 最初期の OOP は 1967 年の Simula67OOP 自体はゼロックスパロアルト研究所(PARC)のアラン・ケイ氏が提唱し Smalltalk (Smalltalk80, 1983年発売)に引き継がれた(Alan Kay:  GUI を発明、ダイナブック構想を提唱)。コードの修正や保守、再利用が簡単となった。

 当初、「『オブジェクト』が『メッセージ』をやりとりすることでコンピューティングを行う」ことを意味していた。すなわち、オブジェクト指向は、コンピュータを動かすソフトウェア(OS)として開発されていた、らしい(そもそも Smalltalk は OS として開発された, Wikipedia 情報)。

 後にビャーネ・ストロヴストルップC++ (1983年)の開発を通じて「カプセル化 encapsulation、継承 inheritence、多態性 polymorphysm」の概念を追加した。現在では、この 3つが、「OOP の特徴」として言及されることが多い。

 OOP が出てきた結果、ソフトウェアの再利用部品群(クラスライブラリフレームワーク)が開発されることとなった。その有用性から、現在では多くのプログラミング言語に取り入れられている。

 

現在の多くの言語が OOP (やライブラリ)を取り入れている。

OOPL の例としてあげられるのは、

 Simula67, Smalltalk, C++, Perl, Python, Java, Ruby, C#...

など。

 

 「オブジェクト」「クラス」等の説明

・・・以下、ややこしいですが、「クラス」「メソッド」などの説明。プログラミングを少しかじると、分かると思われ・・・

 

一般に、オブジェクトはすべてのクラスを含むスーパークラスである

「Object」のサブクラスに「Number」「String」・・・などがあり、「Number」のサブクラスに「Int」「float」・・・などがある、といった構造らしい。

 

 

 

クラスは、データとメソッドから構成される。

 データとは、処理される数値や文字列などのこと。クラスに属する具体的なデータをインスタンスという。

 例えば「Cat」クラスのデータとして「タマ」「トラ」「ミケ」インスタンスが属する。

 メソッドとは、処理のこと。

 

メソッド(method)とは

 プロシージャーまたは関数の一種であり、クラスに所属するサブルーチンメンバー関数 (member function) とも言われる"

 

プロシージャー(procedure)とは

 プログラミング言語によって定義は異なるが、一般的には複数の処理を一つにまとめたもの。手続きと訳され、ルーチンまたは関数とも言う。プログラム全体のルーチンをメインルーチン、呼び出されるものをサブルーチンとも言う。保守、管理を容易にする手法。

 

インスタンスメッセージをやりとりすることでシステムが動作する。

 メッセージとは、オブジェクト間のデータの送受信。

 

メッセージは相手のクラスによって、異なって解釈される。これが多態性 Polymorphysm 

 

メッセージ自体は処理を定義していない。クラスに含まれるメソッドに処理が記載されている。このため、異なるクラスに同じメッセージを送った場合でも、異なる動作を行うことができる。これがポリモーフィズム

・・・以上・・・

 

 

 

 

OOP の3つの特徴 として言われるのは、

 カプセル化 encapsulation クラスなどを利用することで、インスタンスやメソッド、データ型などを見えなくすること。カプセル化により、プログラムの変更が容易になる。例えば色を扱うとき、RGBカラーを扱うプログラムを、CMYKへと変更するとき、より少ない手間で変更できる、みたいな。Javaでは、変数に private をつけることで、ローカル関数としてしかアクセスできなくする。Java には3つのアクセス修飾子public, protected, private) が存在し、この設定により、どこからアクセスできるかを決定する。

 ポリモーフィズム polymorpism メッセージが多様に解釈されること。

 継承 inheritance クラスを、他のクラスへと引き継ぐこと。引き継ぎ元がスーパークラス、引き継ぎ先がサブクラスと呼ばれる。

 複数のスーパークラスから引き継ぐのが多重継承で、これは便利な反面、プログラムが複雑化する原因ともなる。Ruby では多重継承を制限しており、複雑さを避けるため、 Mix-in と言う方法でしか多重継承できない。他の OOP, 例えば JavaPython は一般的な多重継承をサポートしている。

 

 

OOP の定義には含まれないが、OOPL に一般に含まれるもの

 パッケージ:複数のクラスをまとめたもの。これを導入することでプログラムが簡潔に記載できるようになる。パッケージは、名前が一致(衝突)しないように開発されている。

 例外:エラーが発生した場合、処理を中断してエラーを返す仕組み。

 ガベージコレクション:不要になったメモリを(自動的に)解放する機能。これがないプログラムでは、メモリの解放を明示的に指定しなければならず、プログラミングが大変になる。

 TensorFlow ではビデオメモリが不要になっても解放されないので、ほんと困る。複数の処理を立ち上げようとしても立ち上がらなかったり。

 

 

変数グローバル変数、ローカル関数、インスタンス変数

 それぞれアクセス可能範囲が異なっている。

 必要に応じて使い分けましょう。

 グローバル変数はプログラムのどこからでもアクセスできるため便利だが、どこからでも変更される危険があるため仕様に注意が必要。ローカル関数などはその逆。

 

 

型付け,型チェック:静的型付け、動的型付け

 静的型づけコンパイル時に型のエラーを検出する:Java, C#

 動的型づけ:プログラムの実行時点でエラーを検出する:Ruby, Python

 

 

「強い型付け・弱い型付け」は「静的型付け」に対して使われる単語らしいが(型付けとは (カタヅケとは) [単語記事] - ニコニコ大百科)定義が曖昧なので(C#は強い型付けの言語?それとも弱い型付けの言語? - 猫とC#について書くmatarilloの雑記使うべきではない用語のようだ。

 

「入門Python3(オライリー)」では、強い型づけ(Strong typing)

 「クラスがイミュータブル(変更不可能)であること」

と書いている。

 

 

 

プログラミング言語の歴史

機械語(machine code, machine language): 0, 1 によって書かれたプログラム。ヒトには理解しにくい。

アセンブリ言語(assembly laguage):1940年代から使用されてきた。簡単な単語によって書かれ、アセンブラコンパイラの一種)によって機械語に変換される。代表的な低級言語(low-level language)。マシンのリソースが限られている場合には、現代でも使われる場合がある。

高級言語(high-level language):人間が理解しやすい文法を持った言語。1957年のFORTRAN, 1960年のCOBOLが例としてあげられている。

構造化言語(structured programing):1967年(奇しくも SIMULA67 が世に出たのとと同じ年?)にオランダのエドガー・ダイクストラ氏によって提唱。プログラムを好きな順序で実行できる GOTO 文を廃止し、移動を「巡行」「分岐(if)」「繰り返し(for, while)」の3つに限定。構造化言語とされるプログラミング言語には ALGOL, Pascal, C などがある。

 巡行は、BASICで10, 20, 30, とプログラムを書いていたところに、後から 4行目に 15 と2番目の行を追記するやつ ができなくなるのかな?

 

 

プログラム実行方式

コンパイラ方式:機械の理解できる機械語に翻訳(コンパイル)してから実行する。コンパイル後のソフトウェア実行速度は速いが、コンパイルの手間がかかる。コンパイル後、他のOSに移植することはできない。C++

インタプリタ方式:実行時に機械語に変換。実行速度は遅いが、一般にOSに依存せず、共通の仕様を実現できる。Perl, Python, Ruby. これらは、同じ作業を実装するために必要なコード記載量が少ないという特徴もあり、マシンリソースが潤沢な環境では良い選択枝。マシンリソースが限られている場合には vice versa

中間コード方式:実行前にコンパイルするが、機械語ではない中間コードまでコンパイルする。両者のいいとこ取りでOSに依存しない、比較的早い。Java, C#

 

 

プログラムのメモリ利用

静的領域(static):プログラムの開始時に確保され、プログラムが終了するまで確保される領域。

シープ領域:プログラムの実行時に動的に確保するための領域。

スタック領域:スレッド制御のために使う領域。スタック、すなわちデータをどんどん積み重ねていく。

 

 

OOP に関連した再利用技術

 クラスライブラリ フレームワーク コンポーネント:これらは名前は違うが、ほぼ同じもの。

 クラスライブラリ:複数のクラスをまとめて提供するもの。ディープラーニングでよく出てくる TensorFlow は、トップに「An open-source software library for Machine Intelligence」と記載OOP ではプログラミング共通部分(言語仕様)はコンパクトにまとめ、必要な様々な機能はクラスライブラリとして提供するのが一般的。これによりプログラム本体の変更は最小限にとどめることができる。クラスライブラリは大幅に変更されることがあり、OOPを使いこなすには、クラスライブラリを使いこなす必要がある。フレームワークは複数の意味を持ちうる。クラスライブラリと同じ意味のこともあるが、開発・実行環境などを表す「Webアプリケーションフレームワーク」とか使われる場合もあり、クラスライブラリよりも広い概念のようである。日本発のディープラーニングフレームワークChainer: 「A Powerful, Flexible, and Intuitive Framework for Neural Networks」と記載。さて、ライブラリとフレームワークはどこが違うのか?同じなのか? コンポーネントVisual BasicJava で、商品として提供された再利用部品群らしい。

 

システム開発への OOP の応用

デザインパターン(design patterns):優れたライブラリ設計のアイデアを後から再利用できるように名前をつけて文書化したもの。クラスライブラリなどから抽出され、そしてクラスライブラリなどを作るために再利用される。1995年、GoFの著書、「Design Pattern」によって広く世に知られるようになった。

 

オブジェクト指向を利用したシステム開発では、データをまとめたり、メソッド(クラス内に存在するサブルーチン)にクラスを応用することで、開発を簡略化できた。どのようなデータをどのように処理するかなど、何をどうプログラミングするかなど全体のデザインを決める上流工程でも、下流工程、実際の開発や製造すなわちプログラミングなど で OOP をどう生かすかを考える様になった。

 

UML, Unified Modeling Language:ソフトウェアの機能や内部構造を2次元の図に表現する形式を定めた世界標準。以前は多数の表記法が、様々なメソドロジストによって提唱されていた。3人のメソドロジストが1990年代中盤にまとめ、OMG(Object Management Group)が採択したことで広まった。

UMLの使い方

OOPを表現する:クラス図(クラス間の関係、継承などを表記)、シーケンス図(時系列的な動作)、コミュニケーション図(動作時のオブジェクト間のやりとり、すなわちメッセージ)

OOPをどう利用するか:ユースケース図(どのようにプログラムを使うか)、アクティビティ図(時系列的な業務の流れ。シーケンス図に似ている)、ステートマシンズ(状態遷移図と同一。業務フローチャート的な)

 

どのように開発するのかを決めるにはUMLを使ったモデリング、すなわち、図示することで理解が深まるため、システム開発を円滑にすることが期待される。

 

アジャイルAgile)ソフトウェア開発

従来のウォーターフォール型ソフトウェア開発(に対する言葉。小さなリリースを繰り返しながら段階的にソフトウェアを作り上げる。

ウォーターフォール型ソフトウェア開発とは、開発プロジェクトを時系列に、「要求定義」「設計」「プログラミング」「テスト」などの作業工程に分割し、前工程を完了してから次工程に進む開発手法。背景としてプログラミングが進行するにつれて前工程の変更コストが大きくなることがある。このため、変更を少なくし、開発の進捗を管理するのに有効な方法であった。

 将来の見通しが(一見)立てやすいメリットがあるが、プログラミングは実際には予定通りに進むことは少なく、時に「デスマーチ」に突入する。「みずほ銀行 システム開発」等の検索結果参照のこと。

 開発において、「要求定義」「設計」の成果物として大量の文書が発生するがこれは「プログラミング作成のコストよりも文書作成のコストの方がずっと低いこと」が背景にあった。

 問題点として、1.仕様変更(現場の仕様変更の希望に追従しにくい)、2.全体テストが最終段階にある(全体像に関わる問題が最終段階になるまで気付かれなくなり、変更コストが上昇する)ことがある。

アジャイル型ソフトウェア開発(初出, 2001年)反復型開発プロセスとも言う。開発対象の小さな機能に分割し、1つの反復 (イテレーション:1-4週間程度の期間)で1つずつ機能を開発し、それら中間リリースごとにユーザーからフィードバックをもらい適切なソフトを開発していく手法。反復を繰り返すことで開発を進めていく。要求定義、設計、実装、テスト、文書化といった全ての工程を、1つの反復内で行う。反復が終了するごとにプロジェクトにおける優先度を評価し直す。ウォーターフォール型と比べて見通した立ちにくいが、実態に合った開発手法である。

RUP, Rational Unified Process(ラショナル:理性的な統一プロセス):RUP は商用の開発プロセスであり、ラショナル・ソフトウェア社(UML標準化に大きな役割を果たした。2003年に IBM により買収)後に IBM 社により販売されている。

エクストリーム・プログラミング(extreme programming, XP, 初出1999年)は Agile開発の一種というか。Agileよりも先に出てきたもので、書籍で提案された概念?。その特徴は、テスト駆動、ペアプログラミングリファクタリング等、19の「プラクティス」と称される。従来は開発が進むにつれ変更コストは大きくなることから、変更が少なくてすむ(予定の)ウォーターフォール型の開発がなされてきた。XPでは様々な対策により、変更コストが大きくならないように工夫し、変更に対する柔軟性を実現する。ソースコードプログラマ中心のアプローチであり、それゆえ発注者・管理者側の忍耐が必要な開発手法である。「テストがうまくいったら鐘を鳴らして皆で喜べ」とか「お菓子を食べながらプログラミングせよ」などと書かれているらしい。

 

テスト駆動(Test Driven Development, TDD):まずテストコードを作成し、テストが失敗することを確認する。次に本体コードを作り、テストを通ることを確認。さらにリファクタリングする。不具合の早期発見、仕様変更への早期対応、モジュールの独立性維持などに役に立つ。

リファクタリング(refactoring):完成したプログラムの外部仕様を変えずに、内部構造を改善する。書籍「リファクタリング(1999年)」年に詳しく記載。従来は「動いているコードに触るな」が常識だったが、ソフトウェアを長期間にわたり、手を加えて使い続けるために有用なプラクティス。

継続的インテグレーション(Continuous Integration, CI):専用のマシン環境を用意し、数時間おきにテストを実行すること。モジュールの統合でトラブルが発生しないように、問題点を早期発見する。xUnit は様々な言語の単体テストフレームワークを総称する単語。JavaJUnit、.NETのNUnitRubyのRubyUnit、Pythonのunittestなどを総称。

ペアプログラミング:一人がコードを書く、もう一人がレビューをする(定期的に入れ替える)ことで、コードの質を改善するほか、コードの相互理解に繋がり、保守できる人を絶やさないようにする手法。

 

OOP後のトレンド

アスペクト指向プログラミングOOPを使っても、プログラムの様座な部分に分散してしまう共通な処理を分離して記述する仕組み(横断的関心と呼ぶ)。

エージェント指向プログラミング:能動的に活動する「エージェント(ユーザーの代理)」を設定。外部からのメッセージ受信により初めて仕事をするOOPに大使、エージェントを中心にプログラムを作り上げる。では「エージェント」とは具体的になんなのかは、はっきりしていない。

サービス指向:複雑で巨大化したシステムを、独立性の高いサブシステムの集合に作り替えると言うコンセプト。 

関数型言語プログラミング言語の仕組み。OOPと対立する概念ではなく、OOPかつ関数型の言語もある(例:Python)。対立する概念は命令が多言語で、機械語を表す単語を組み合わせてプログラムを記述する。7つの特徴がある。関数型プログラミングの平行が異変として、命令的プログラミング(従来のプログラミング)や論理プログラミング(logic programming)がある。

 

関数型言語の特徴

関数でプログラムを作るOOPではクラスとメソッドを使う(引数を指定して関数を呼び出す)。関数型では関数:引数と戻り値を必ず持つ を使う(引数に関数を適用する)。

すべてが式。すべての式が値を返す:従来の命令的プログラミング(imperative programming)では命令(statement)を実行(execute)する手続き的プログラミング(procedural programming)と言われるところ、式(expression)を評価する(evaluate)ことでプログラムが進行する宣言型プログラミング(declarative programming)と言われる。関数や計算のみならず、データに対しても値を返す。必ず値を返すため、関数型言語で、式は return ステートメントがない(ことが一般的)。

関数を値として扱える:関数を引数や戻り値として扱うことができる(高階関数,higher order function)

関数と引数を組み合わせられる:「部分適用」二つ以上の引数を持つ関数において、一部の引数だけを適用して別の関数を作成する(これをカリー化と呼ぶ:Haskell Curry 氏の名前より)。「関数の合成」

副作用を起こさない:副作用とは、「引数から戻り値を求める以外の仕事」。副作用を認めない関数型言語純粋関数型言語。引数を一度設定したら変更できないため、変数に値や式を設定することを代入(substitution)と呼ばず、2度と変更できないことから束縛(binding)と呼ぶ。副作用がない場合、引数が同じなら戻り値も同じになる。これを参照透過性(referential transparency)とよぶ。

 遅延評価(lazy evaluation)は式を上から評価するのではなく、必要になった時点で個々の式を評価する仕組み。

場合分けと再起でループを記述する:for や while は関数型言語と相性が悪い。終了判定のための変数を制御できないらしい。一般にパターンマッチと再起でループ処理を行う。パターンマッチは引数の値に応じて場合分けし、関数を定義するしくみ。

コンパイラが型を推測する(型推論 type inference):型変数と呼ぶ仮の型をコンパイル時に指定。型変数を使って定義した型のことを多層型と呼ぶ。ポリモーフィズムとは違う仕組みである。

 

 

プログラミング言語リスト 

OOP以前の高水準言語

FORTRAN(1957年):史上初の高水準言語(ジョン・バッカスIBM)。「数式翻訳」を意味する英語「formula translation」に由来する。最新バージョンは2008(2010年)。現在でもスーパーコンピュータ向けの言語として、C/C++と共に提供される。

LISP(1958年)関数型プログラミング言語らしい(ジョン・マカーシー)。いろいろと先進的な部分があり、多くのプログラミング言語に影響を与えた、らしい。関数型言語 (functional language)は、「関数型プログラミングを基本スタイルとして推奨する機能を持つプログラミング言語」で、その例として他に Haskell(1990年)、Scala(2003年)、Julia (2012年)がある。

ALGOL(1958年):命令型プログラミング言語。「アルゴリズム言語」を意味する英語「algorithmic language」に由来。ヨーロッパの研究者が、世界共通のプログラミング言語として開発した。1958年にチューリッヒ工科大学で行われた国際会議で提案されたのが起源とされる。多くの言語に影響を及ぼし、ACMや教科書や学術論文などでアルゴリズム記述のデファクトスタンダードとして30年以上使われた。使われ「」。「使われた

COBOL(1959年):グレース・ホッパーその他。アメリカ合衆国の強い関与の元で作られた言語で、政府や公的機関を中心に採用されていた。Common Business Oriented Language

 

OOP以降

Simula67:1967年登場(オルヨハン・ダール、クリステン・ニガード:ノルウェー)。最初期の OOP と言われているシミュレーション目的に作成されたプログラミング言語。SIMUlation LAnguage の abbriviation で、ALGOL60を拡張する形で1960年代に開発が始められた。

C言語 :1972年 AT&Tベル研究所にて開発。OOPではない。あらゆるコンピューターで動く古い言語で汎用性が高く、動作も速い。実行にはコンパイルが必要。低級言語と高級言語の両方の特徴を持ち、習得が難しい。C++, Java, C# など、様々なプログラミングの基礎となっている。

MATLAB:1970年代にクリーブ・モラーによって開発。学生がFortranを学ぶことなくLINPACKやEISPACKにアクセスできるようにと設計した。これを販売するために Mathworks 社が設立され、現在では半年に1度のバージョンアップを繰り返している。

Smaltalk:1980年公開。世界初のオブジェクト指向プログラミングを謳った言語? ゼロックスパロアルト研究所(PARC)で1970年代に約10年かけ3世代(Smalltalk-72、76、80)を経て整備された。元々は dynabook 「Alto」 の OS として開発された。現在はシンコムより VisualWorks(ビジュアルワークス)という製品名で主要なオペレーティングシステム向けに販売されている。

C++:1983年登場(ビャーネ・ストロヴストルップ:デンマーク)。Cの拡張版で、当初の名前は C with class であったことから分かるとおり、OOPである。クラス、仮想関数、多重定義、多重継承、テンプレート、例外処理といった機能が追加されていった。

Objective-C:1983年(ブラッド・コックス:米)。ほぼ MacOS, iOS の開発専用言語だが、2014年に Swift が出たことで今後はどうなるか。

Perl:1987年(ラリー・ウォール:米)、 AWK、BASIC-PLUS、C、C++LISPPascalsed, シェルスクリプトなどに影響を受けて作成された、コンパイル不要な動的型付け言語。元々はOOPではなかったらしい。

Python:1991年(グイド・ヴァンロッサム:蘭)。Google 3大言語の一つ(C++, Java, Python)。元々はOOPではなかったということ。

Java:1995年登場(サンマイクロシステムズ, OOP)。Java Runtime Environment JRE を使う。Java とは 開発施設の近くにあった喫茶店の名前から、とか、いくつかの由来が言われている。元々は Oak と言う名前で開発されていたが。CやC++などから多くを引き継いでいる。C++になかったガベージコレクションが追加されている。コンパイル時に中間言語コンパイルされてJavaプラットフォーム(JVM)上で動作するため、特定のOSに依存しない。プログラミング言語人気ランキング1位の常連である。

JavaScript:1995年に登場(ネスケ/Mozilla)。スクリプト言語。主にブラウザ上で実行される。JavaJavaScriptは名前は似ているが、パンとパンダくらい、オーストリアとオーストラリアくらい違うらしい。

Ruby:1995年(Mats:日)。PerlSmalltalk、Eiffel、Ada、Lispの一部をブレンドして作成された、 関数型プログラミングと命令型プログラミングが絶妙に調和された新しい言語。

php:1995年登場(1995年はプログラミング言語特異点だ。ラスマス・ラードフ:加:オランダ系)。名称の PHP再帰的頭字語である "PHP: Hypertext Preprocessor" を意味し、「PHPはHTMLのプリプロセッサである」とPHP自身を再帰的に説明している。Webページを作成することに特化した言語らしいが、いろいろだめなところが多いため、定期的にネタにされる。それでも初心者が学びやすいらしく、プログラミング言語人気ランキングをすると大体10位までに入ってくる。

R言語:1996年登場(Ross Ihaka, Robert Clifford Gentleman:ニュージーランドオークランド大学)。動的型付け関数型・オブジェクト指向プログラミング言語。統計解析向けとして開発されたフリーソフトウェアだが多機能で、機械学習ディープラーニングにも使用されている。ニュージーランドオークランド大学のRoss IhakaとRobert Clifford Gentlemanにより作られた。

C#:2002年マイクロソフトが開発。Microsoft .NET Framework 上で動き、Linux上でも(互換ソフトにて)動く。C++, Delphi, Eiffel, Java, LISP に影響を受けた。