Tensorflowをあらためてやってみた。
あらためてTensorflowをやってみた。以前より理解は進んでいる気がする。
#coding:UTF-8 import input_data mnist = input_data.read_data_sets("MNIST_data/", one_hot=True) import tensorflow as tf ## 画像は28*28ピクセル = 784ピクセル ## この画像から0,...,9という番号を判断したい。 # 入力変数定義 float32型で、(None, 784)の2階のテンソルを作る。 x = tf.placeholder(tf.float32, [None, 784]) # 重み 初期値ゼロで(784,10)の2階のテンソルを作る。 W = tf.Variable(tf.zeros([784, 10])) # バイアス 初期値0で(10)の1階のテンソルをつくる b = tf.Variable(tf.zeros([10])) # ソフトマックス活性化関数 y = tf.nn.softmax(tf.matmul(x, W) + b) # 正解 right_answer = tf.placeholder(tf.float32, [None, 10]) # クロスエントロピーの定義 (最小二乗法でも良かったが) cross_entropy = -tf.reduce_sum(right_answer*tf.log(y)) # 勾配降下法で重みを調整する # 学習比率 0.01 train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy) #初期化 init = tf.initialize_all_variables() sess = tf.Session() sess.run(init) # 学習中 for i in range(1000): # データを取得 1回で100個のデータ(バッチ)を持ってくる batch_xs, batch_ys = mnist.train.next_batch(100) # ステップを実行 sess.run(train_step, feed_dict={x: batch_xs, right_answer: batch_ys}) ## 結果表示 ## # それぞれの分布から最も確率の高いもの同士を見比べ同じであるかを調べる。 correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(right_answer,1)) # 正答率を計算する。 accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float")) # 精度表示 print(sess.run(accuracy, feed_dict={x: mnist.test.images, right_answer: mnist.test.labels}))
StoreKitメモ
SKProductRequest
initWithProductIdentifiers:でプロダクトIDを指定しプロダクト情報を取得するリクエスト(SKProductsRequest)を作成する。
これは非同期で結果がかえる。
didReceiveResponse、didFailWithError、requestDidFinish。
SKProductsResponceに結果が入っている。
SKProductsResponce
ここからSKProductが取れる。
SKProduct
ここからlocalizedTitle,localizedDescription, price, priceLocale, productIdentifier等が取得できる。
プレゼンタに加えてドメイン層を入れる
プレゼンタを導入した後は今回はさらにドメイン層(UseCase)を取り入れたい。
プレゼンタ
プレゼンタはUseCaseにまとめられた処理を用いてビューないしUseCaseからの返事を処理する。
Adaptive Design
Size Class
以下を参考
qiita.com
各種UI部品のUITaraitCollectionでの変化
以下を参考
qiita.com
- UISplitViewController Master/Detailの両方が見える時、Masterだけが見える時
- Presentation Controller
- UIAppearance
show
ViewControllerの階層関係を気にせず次のvcを呼ぶメソッド
親は適宜、targetViewController(forAction 、を実装し、そのshowができるvc(例えばナビゲーションvc)を見つける。
showを実装しているvcは委譲されて実行される。
FaceBookグラフ
単に以下のようにやるだけでJSONが返却される。
let req = FBSDKGraphRequest(graphPath: "me" , parameters: ["fields":"id,email,name"]) req?.start(completionHandler: { (con, result, error) in if let error = error { print("error") return } print("\(result)")
実際に取れる内容はグラフのエクスプローラでweb上で試してみることができる。
Graph APIエクスプローラ - 開発者向けFacebook
FaceBookログイン
基本はdevelopers.facebook.com
にすべて書いてある。
フレームワークとしてFBSDKCoreKit、FBSDKLoginKitあたりをDLして入れる。ここでpodを使っても良い。
info.plistの設定でFaceBookAppIDの文字列を間違えないようにする。
FBSDKCoreKitのFBSDKApplicationDelegateへAppDelegateのメッセージを流すようにする。
ログイン処理はFBSDKLoginKitを使う。
便利UIとしてFBSDKLoginButtonがすでに用意されている。FBSDKLoginButtonDelegateでログイン結果を受け取る。
ログインで得たトークンはキーチェインに保存されるので、キーチェインの使用を許可(Capabilitiesで)しておく。
FBSDKAccessTokenのcurrentで現在のトークンがわかるのでログイン済みかは判断できる。そこからユーザIDを取得できる。
ハフマン符号
"AABABCAC"を単純にbitを割り当てるとA 00, B 01, C 10のように1文字に2ビットで、計16ビットかかる。
出現頻度を調べる。
"AABABCAC"のAは4、Bは2、Cは2で現れる。
ハフマン木をつくる。
最も低い出現頻度とその次のものを取ってくる。今は,B,C。
{B,C}
次の出現頻度のものはAなので
{A,{B,C}}
というハフマン木ができる。
根元から0,1をふっていく。
A = 0
B = 10
C = 11
よってハフマン符号によって
0 0 10 0 10 11 0 11
で、計12ビットに圧縮できた。
復号方法
"0" 0 10 0 10 11 0 11 ... ハフマン木に0*はないのでA確定
A "0" 10 0 10 11 0 11
A A 10 0 10 11 0 11
以下同様にハフマン木を見ていけば復号できる。
A A B A A B A B
参考したサイト
insertion sort 挿入ソート
O(n^2)な実行時間。ほぼ整列している場合は非常に速い。
1. 先頭から整列してない数を探す。
2. その数を整列させるように差し込む。
- 2,3,5,4,2
- 2,3,5,"4",2
- 2,3,"4",5,2
- 2,3,4,5,2
- 2,3,4,5,"2"
- "2",2,3,4,5
ドメイン駆動
参考にしたもの
ドメイン駆動設計 ( DDD ) をやってみよう
ドメイン駆動設計のためのオブジェクト指向入門
実践に向けたドメイン駆動設計のエッセンス
3つのレイヤー
ポイント
ドメインを隔離する。UIとデータ形式から。生のデータを使わない。結果は加工されたモデルを渡す。
計算、加工、判断のロジックを一箇所に集めること。実現手段の隠蔽。各自の型の定義(基本データ型を使わない)。値オブジェクト。一覧オブジェクト。
(if,list,string,etc)も使わない。
プレゼン層はプレゼンタからドメイン層を使うがドメイン層はプレゼン層をつかわない。
ドメイン層のユースケースはリポジトリを介してデータを受け取るがそれはモデルの形にしてプレゼン層に渡す。
トランスレータはモデルの変換を行う。
業務の関心事にドメインオブジェクトを作り、公開メソッドは業務と関連するものにする。
ルールのクラス化
- Procedure(手順) 状態を持たない
- Policy(ポリシー) ルールの集まり。状態を持たない
- Rule(ルール) 集まって一つのポリシーを作る
集約(アグリゲート)
一緒に使うもの部品をあつめた一つのクラス
ReSwiftの流れ
ReSwiftというSwiftのRedux実装のライブラリを触ってみました。
- アプリはStoreを一個持ちStoreはこちらで定義した状態(State)を持ちます。
- 各種のReducerというのをStoreに登録します。
- ReducerはActionが発行されたらどのようにStateを変更するのか各自で定義します。
- ボタンがタップされたなどのイベントが起きたとき、プログラマはアクションをストアに送ります(dispatch)、するとストアではReducerに今の状態とアクションを食わせて新しい状態にします。
- 新しい状態はそれを監視(subscribe)しているオブジェクトにnewStateとして通知されるという具合です。
擬似コードでのまとめ
State定義
Action定義
各種Reducer定義
Reducer (Action, State) -> State
Store作成
Store = {State, Reducers}
状態更新を受取りたい場合
Store.subscribe(User)
タップのイベント等が起きたことを通知
Store.dispatch(Action)
reducerによってState更新され状態変更が通知される。
ViewControllerはアクションを発行し状態変更通知を受けたら状態に基づいてUIを変更するという流れになります。
参照
簡単なコードサンプルとして
GitHub - ReSwift/CounterExample: Demo Application of Unidirectional Data Flow in Swift, Built with ReSwift
より実際的な実装例は以下にありました。
qiita.com
基本操作
最低限
- 入力モードへの切替はiで、コマンドモードに戻るときはesc
- 保存 :w、保存して終了:wq、終了:q
参考
マルチスレッドのデザインパターン
以下を参照しつつマルチスレッドのデザインパターンを概観し、適宜Swiftでの実装を考える。
Single Threaded Execution (同時にできない)
Immutable (不変)
Guarded Suspension (用意できるまで待つ)
Balking (用意できないならやめる)
Producer-Consumer (生産者と消費者をわける)
Read-Write Lock (書く人は一人、読むのは誰でも)
Thread-Per-Message (処理を他のスレッドに任せる)
Worker Thread (スレッドを貯めておいて仕事を振る)
Future (任せておいた仕事の結果を同期的に受け取る)
Two-Phase Termination (適切な終了処理)
Thread-Specific Storage (スレッド毎に保存できる領域を確保しておく)
Active Object (自律的なオブジェクト)
Switで実装してみた。
github.com
GLKitミニマム2 OpenGL
テンプレートからOpenGL部分を残し、データを三角形の回転するだけに変えてみたもの。
頂点シェーダー
attribute vec4 position;
uniform mat4 modelViewProjectionMatrix;
void main()
{
gl_Position = modelViewProjectionMatrix * position;
}
フラグメントシェーダー
void main() { gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); }
GLKViewController本体
import GLKit import OpenGLES func BUFFER_OFFSET(i: Int) -> UnsafePointer<Void> { let p: UnsafePointer<Void> = nil return p.advancedBy(i) } let UNIFORM_MODELVIEWPROJECTION_MATRIX = 0 let UNIFORM_NORMAL_MATRIX = 1 var uniforms = [GLint](count: 2, repeatedValue: 0) class GameViewController: GLKViewController { var program: GLuint = 0 var modelViewProjectionMatrix:GLKMatrix4 = GLKMatrix4Identity var normalMatrix: GLKMatrix3 = GLKMatrix3Identity var rotation: Float = 0.0 var vertexArray: GLuint = 0 var vertexBuffer: GLuint = 0 var context: EAGLContext? = nil var effect: GLKBaseEffect? = nil deinit { self.tearDownGL() if EAGLContext.currentContext() === self.context { EAGLContext.setCurrentContext(nil) } } override func viewDidLoad() { super.viewDidLoad() self.context = EAGLContext(API: .OpenGLES2) if !(self.context != nil) { print("Failed to create ES context") } let view = self.view as! GLKView view.context = self.context! view.drawableDepthFormat = .Format24 self.setupGL() } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() if self.isViewLoaded() && (self.view.window != nil) { self.view = nil self.tearDownGL() if EAGLContext.currentContext() === self.context { EAGLContext.setCurrentContext(nil) } self.context = nil } } func setupGL() { EAGLContext.setCurrentContext(self.context) self.loadShaders() self.effect = GLKBaseEffect() self.effect!.light0.enabled = GLboolean(GL_TRUE) self.effect!.light0.diffuseColor = GLKVector4Make(1.0, 0.4, 0.4, 1.0) glEnable(GLenum(GL_DEPTH_TEST)) glGenVertexArraysOES(1, &vertexArray) glBindVertexArrayOES(vertexArray) glGenBuffers(1, &vertexBuffer) glBindBuffer(GLenum(GL_ARRAY_BUFFER), vertexBuffer) glBufferData(GLenum(GL_ARRAY_BUFFER), GLsizeiptr(sizeof(GLfloat) * gVertexData.count), &gVertexData, GLenum(GL_STATIC_DRAW)) glEnableVertexAttribArray(GLuint(GLKVertexAttrib.Position.rawValue)) glVertexAttribPointer(GLuint(GLKVertexAttrib.Position.rawValue), 3, GLenum(GL_FLOAT), GLboolean(GL_FALSE), GLsizei(sizeof(GLfloat)*3), BUFFER_OFFSET(0)) glBindVertexArrayOES(0) } func tearDownGL() { EAGLContext.setCurrentContext(self.context) glDeleteBuffers(1, &vertexBuffer) glDeleteVertexArraysOES(1, &vertexArray) self.effect = nil if program != 0 { glDeleteProgram(program) program = 0 } } // MARK: - GLKView and GLKViewController delegate methods func update() { let aspect = fabsf(Float(self.view.bounds.size.width / self.view.bounds.size.height)) let projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0), aspect, 0.1, 100.0) self.effect?.transform.projectionMatrix = projectionMatrix var baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0, 0.0, -4.0) baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, rotation, 0.0, 1.0, 0.0) // Compute the model view matrix for the object rendered with ES2 var modelViewMatrix = GLKMatrix4MakeTranslation(0.0, 0.0, 1.5) modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, rotation, 1.0, 1.0, 1.0) modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix) normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), nil) modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix) rotation += Float(self.timeSinceLastUpdate * 0.5) } override func glkView(view: GLKView, drawInRect rect: CGRect) { glClearColor(0.65, 0.65, 0.65, 1.0) glClear(GLbitfield(GL_COLOR_BUFFER_BIT) | GLbitfield(GL_DEPTH_BUFFER_BIT)) glBindVertexArrayOES(vertexArray) // Render the object again with ES2 glUseProgram(program) withUnsafePointer(&modelViewProjectionMatrix, { glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, UnsafePointer($0)) }) withUnsafePointer(&normalMatrix, { glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, UnsafePointer($0)) }) glDrawArrays(GLenum(GL_TRIANGLES), 0, Int32(gVertexData.count/3)) } // MARK: - OpenGL ES 2 shader compilation func loadShaders() -> Bool { var vertShader: GLuint = 0 var fragShader: GLuint = 0 var vertShaderPathname: String var fragShaderPathname: String // Create shader program. program = glCreateProgram() // Create and compile vertex shader. vertShaderPathname = NSBundle.mainBundle().pathForResource("Shader", ofType: "vsh")! if self.compileShader(&vertShader, type: GLenum(GL_VERTEX_SHADER), file: vertShaderPathname) == false { print("Failed to compile vertex shader") return false } // Create and compile fragment shader. fragShaderPathname = NSBundle.mainBundle().pathForResource("Shader", ofType: "fsh")! if !self.compileShader(&fragShader, type: GLenum(GL_FRAGMENT_SHADER), file: fragShaderPathname) { print("Failed to compile fragment shader") return false } // Attach vertex shader to program. glAttachShader(program, vertShader) // Attach fragment shader to program. glAttachShader(program, fragShader) // Bind attribute locations. // This needs to be done prior to linking. glBindAttribLocation(program, GLuint(GLKVertexAttrib.Position.rawValue), "position") glBindAttribLocation(program, GLuint(GLKVertexAttrib.Normal.rawValue), "normal") // Link program. if !self.linkProgram(program) { print("Failed to link program: \(program)") if vertShader != 0 { glDeleteShader(vertShader) vertShader = 0 } if fragShader != 0 { glDeleteShader(fragShader) fragShader = 0 } if program != 0 { glDeleteProgram(program) program = 0 } return false } // Get uniform locations. uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(program, "modelViewProjectionMatrix") uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(program, "normalMatrix") // Release vertex and fragment shaders. if vertShader != 0 { glDetachShader(program, vertShader) glDeleteShader(vertShader) } if fragShader != 0 { glDetachShader(program, fragShader) glDeleteShader(fragShader) } return true } func compileShader(inout shader: GLuint, type: GLenum, file: String) -> Bool { var status: GLint = 0 var source: UnsafePointer<Int8> do { source = try NSString(contentsOfFile: file, encoding: NSUTF8StringEncoding).UTF8String } catch { print("Failed to load vertex shader") return false } var castSource = UnsafePointer<GLchar>(source) shader = glCreateShader(type) glShaderSource(shader, 1, &castSource, nil) glCompileShader(shader) //#if defined(DEBUG) // var logLength: GLint = 0 // glGetShaderiv(shader, GLenum(GL_INFO_LOG_LENGTH), &logLength) // if logLength > 0 { // var log = UnsafeMutablePointer<GLchar>(malloc(Int(logLength))) // glGetShaderInfoLog(shader, logLength, &logLength, log) // NSLog("Shader compile log: \n%s", log) // free(log) // } //#endif glGetShaderiv(shader, GLenum(GL_COMPILE_STATUS), &status) if status == 0 { glDeleteShader(shader) return false } return true } func linkProgram(prog: GLuint) -> Bool { var status: GLint = 0 glLinkProgram(prog) //#if defined(DEBUG) // var logLength: GLint = 0 // glGetShaderiv(shader, GLenum(GL_INFO_LOG_LENGTH), &logLength) // if logLength > 0 { // var log = UnsafeMutablePointer<GLchar>(malloc(Int(logLength))) // glGetShaderInfoLog(shader, logLength, &logLength, log) // NSLog("Shader compile log: \n%s", log) // free(log) // } //#endif glGetProgramiv(prog, GLenum(GL_LINK_STATUS), &status) if status == 0 { return false } return true } func validateProgram(prog: GLuint) -> Bool { var logLength: GLsizei = 0 var status: GLint = 0 glValidateProgram(prog) glGetProgramiv(prog, GLenum(GL_INFO_LOG_LENGTH), &logLength) if logLength > 0 { var log: [GLchar] = [GLchar](count: Int(logLength), repeatedValue: 0) glGetProgramInfoLog(prog, logLength, &logLength, &log) print("Program validate log: \n\(log)") } glGetProgramiv(prog, GLenum(GL_VALIDATE_STATUS), &status) var returnVal = true if status == 0 { returnVal = false } return returnVal } } var gVertexData: [GLfloat] = [ -0.5, -0.0, 0.0, 0.5,-0.5,0.0, -0.5,0.5,0.0 ]
GLKitミニマム
テンプレートを三角形が回転するだけのコードに削ってみた。
import GLKit import OpenGLES func BUFFER_OFFSET(i: Int) -> UnsafePointer<Void> { let p: UnsafePointer<Void> = nil return p.advancedBy(i) } class GameViewController: GLKViewController { var rotation: Float = 0.0 var vertexArray: GLuint = 0 var vertexBuffer: GLuint = 0 var context: EAGLContext? = nil var effect: GLKBaseEffect? = nil deinit { self.tearDownGL() if EAGLContext.currentContext() === self.context { EAGLContext.setCurrentContext(nil) } } override func viewDidLoad() { super.viewDidLoad() self.context = EAGLContext(API: .OpenGLES2) if !(self.context != nil) { print("Failed to create ES context") } let view = self.view as! GLKView view.context = self.context! view.drawableDepthFormat = .Format24 self.setupGL() } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() if self.isViewLoaded() && (self.view.window != nil) { self.view = nil self.tearDownGL() if EAGLContext.currentContext() === self.context { EAGLContext.setCurrentContext(nil) } self.context = nil } } func setupGL() { EAGLContext.setCurrentContext(self.context) self.effect = GLKBaseEffect() self.effect!.light0.enabled = GLboolean(GL_TRUE) self.effect!.light0.diffuseColor = GLKVector4Make(1.0, 0.4, 0.4, 1.0) glEnable(GLenum(GL_DEPTH_TEST)) glGenVertexArraysOES(1, &vertexArray) glBindVertexArrayOES(vertexArray) glGenBuffers(1, &vertexBuffer)// 頂点バッファポインタ生成 glBindBuffer(GLenum(GL_ARRAY_BUFFER), vertexBuffer)// 有効化 // バッファに転送 glBufferData(GLenum(GL_ARRAY_BUFFER), GLsizeiptr(sizeof(GLfloat) * gVertexData.count), &gVertexData, GLenum(GL_STATIC_DRAW)) // 属性指定に頂点の位置を用いる事を指定 glEnableVertexAttribArray(GLuint(GLKVertexAttrib.Position.rawValue)) // glVertexAttribPointer(GLuint(GLKVertexAttrib.Position.rawValue), 3,// 1頂点あたりの要素の数 三次元なのでx,y,zの3 GLenum(GL_FLOAT), GLboolean(GL_FALSE), // ノーマライズされているか GLsizei(sizeof(GLfloat)*3), // 格納されているデータの間隔 BUFFER_OFFSET(0)) // データは並んでいる。 glBindVertexArrayOES(0) } func tearDownGL() { EAGLContext.setCurrentContext(self.context) glDeleteBuffers(1, &vertexBuffer) glDeleteVertexArraysOES(1, &vertexArray) self.effect = nil } // MARK: - GLKView and GLKViewController delegate methods func update() { let aspect = fabsf(Float(self.view.bounds.size.width / self.view.bounds.size.height)) let projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0), aspect, 0.1, 100.0) self.effect?.transform.projectionMatrix = projectionMatrix var baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0, 0.0, -4.0) baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, rotation, 0.0, 1.0, 0.0) // Compute the model view matrix for the object rendered with GLKit var modelViewMatrix = GLKMatrix4MakeTranslation(0.0, 0.0, -1.5) modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, rotation, 1.0, 1.0, 1.0) modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix) self.effect?.transform.modelviewMatrix = modelViewMatrix rotation += Float(self.timeSinceLastUpdate * 0.5) } override func glkView(view: GLKView, drawInRect rect: CGRect) { glClearColor(0.65, 0.65, 0.65, 1.0) glClear(GLbitfield(GL_COLOR_BUFFER_BIT) | GLbitfield(GL_DEPTH_BUFFER_BIT)) glBindVertexArrayOES(vertexArray) // Render the object with GLKit self.effect?.prepareToDraw() glDrawArrays(GLenum(GL_TRIANGLES) , 0, Int32(gVertexData.count/3)) } } var gVertexData: [GLfloat] = [ -0.5, -0.0, 0.0, 0.5,-0.5,0.0, -0.5,0.5,0.0 ]