2/4

メガネを調節をしに渋谷のパリミキへ行った。前通っていたパリミキは落ち着いていた普通の雰囲気であったが、この店は全く違う。何が違うというと、内装がナンバープレートとかピアノとかだったり、商品の半分がグラサンだったり、どう見てもサブカル系。童貞のおっさんが来るところでわない。レイバンもあったよ。

あたりはリア充若者が満載なのに、童貞のおっさんが一人座っているのはどう見ても晒し者。挙げ句の果てにそのまま放置プレイされるしで死にたくなった。早く殺してくれ。

グラサンのお兄ちゃんは見た目とは正反対で驚くほどちゃんと対応してくれた。でも、もうあんな恥ずかしいプレイはしたくないので行かない。でもおっさんのメガネとか渋谷のどこで買えばいいんだ。眼鏡市場とかか。執事眼鏡でてーちゃんの眼鏡が出てくれればそれ買うので早く売り出してくれ。

2/3

たまにはBlogでも始めるか(1年ぶりn回目)。

  • ジムでリカンベントバイクしながら過去問道場するの、何ら後ろめたさを感じる事が無い時間を過ごせるのでよい。セキュスペの勉強ほとんどしてないからやばい。2月中に午後問やるくらいの事をしなければならない。

  • ゲームが辛い。BtoWはイーガ団は突破できたものの、ロリと一緒に突入した3連ドラムが難しくて詰んでる。オクトラはトレサ4章に入って、RPGの「ラスボス前になるとやる気が無くなる病」にかかってやる気があまりない。スマブラは灯火でラスボス前にも行ったけど、これまたこの病にかかってしまいやる気がいまいち。この病なんとかしたい。

  • ピカブイはヤマブキで積んでしまっている。

  • 恵方巻安くないし、コスパも悪いので、ネギトロを買ってネギトロ丼にした(満足した)。

  • ロータスラビリンスが延期になってしまった。今度割引になったらふし幻買いたい。

  • Linuxの日本語文字入力がポンコツで辛い。ATOK入れたい。

  • DNNで使う予定だったGPUが仕事してない。ゲームにも使って無いし悲しい。

  • お金使い過ぎなので節約しなければならない。

TensorFlowでUnpooling Layerの実装

やりたいこと

これ

f:id:usagisagi:20180704212410j:plain

[1711.08763] DeepPainter: Painter Classification Using Deep Convolutional Autoencoders

やったこと

全コードは下記参照。

memo/unpool.py at master · usagisagi/memo · GitHub

nn.max_pool_with_argmaxscatter_ndを使う。max_pool_with_argmaxする前のshapeを取って置くことと、scatter_ndを1次元に配置してから行うことがコツ。

def pooling(input: Tensor,
            ksize,
            strides,
            padding: str = 'VALID',
            name: str = 'pooling') -> Tuple[Tensor, Tensor, TensorShape]:
    """
    pooling層。実質pool_with_arg_max。

    :param input:
    :param ksize:
    :param strides:
    :param padding:
    :param name:
    :return:
        次ノードへのTensor, argmax、inputのshape
    """
    with tf.name_scope(name):
        input_shape = input.get_shape()
        output, argmax = \
            tf.nn.max_pool_with_argmax(input, ksize, strides, padding)
        return output, argmax, input_shape


def unpooling(input: Tensor,
              argmax: Tensor,
              output_shape: TensorShape,
              name='unpooling'):
    """
    unpooling層

    :param input:
    :param argmax:
    :param output_shape:
    :return:
        次ノードへのTensor
    """

    with tf.name_scope(name):
        # inputを直線に並べる
        input_stride = tf.reshape(input, [-1])

        # argmaxを直線に並べる。1行1要素の2次元になる。
        argmax_stride = tf.reshape(argmax, [-1, 1])

        # outputの要素数
        num_elem = output_shape.num_elements()

        # inputをargmaxに従い、num_elemの1行Tensorに再配置
        output_stride = tf.scatter_nd(argmax_stride, input_stride, [num_elem])

        output = tf.reshape(output_stride, output_shape)

        return output

TensorFlowで保存済モデルからのVariable抽出

ニューロンとか可視化したいときとかに

import tensorflow as tf

# グラフ構造import
saver = tf.train.import_meta_graph('models/my_model_final.ckpt.meta')

# sessionにグラフ構造をrestore
sess = tf.Session()
saver.restore(sess, 'models/my_model_final.ckpt')

# variablesのリストを取得
tvars = tf.trainable_variables()

# 値の取得
vars = sess.run(tvars)

https://github.com/google/prettytensor/issues/6

VBAとjar間で対話的に標準入出力を行う

背景

つかっているシステムがVBAだった

VBAクラス

モジュールでなくクラスなので注意

' 対話的にjarとやり取りを行う
' JarOperator.cls
Option Explicit
Dim Wsh As Object
Dim Exec As Object

' jar側の標準入力完了サイン
Const EOS = "EOS"

' 標準出力を取得
Public Function AquireStdOut(St As String) As String

    Exec.StdIn.WriteLine St
    
    Dim Line As String, nLine As String
    Line = vbNullString
    nLine = vbNullString
    
    ' jar側には終わりのサインをつけるようにする
    Do While nLine <> "EOS"
        Line = nLine
        nLine = Exec.StdOut.ReadLine
    Loop
    
    AquireStdOut = Line
End Function

' 実質コンストラクタ
Public Sub SetJarPath(Path As String)
    
    ' jarファイル呼ぶときダブルクオーテーションで囲まないといけない
    Path = """" + Path + """"
    
    Dim cmd As String
    cmd = "java -jar " + Path
    
    Set Wsh = CreateObject("WScript.Shell")
    Set Exec = Wsh.Exec(cmd)
    
    ' 標準入力待ちまで繰り返す
    Exec.StdOut.ReadLine
End Sub

Private Sub Class_Terminate()
    ' 後始末
    Exec.Terminate
    Set Exec = Nothing
    Set Wsh = Nothing
End Sub

使い方

以下のようなjarファイルを作ります

// ShellTest.scala => ShellTest-assembly-0.1.jar
object Test {
var isFirst = true

def main(args: Array[String]): Unit = {
    if (args.length != 0) println(args(0))
    println("launched")
    io("")
}

def io(str: String): Unit = {
    // 実際は分岐させること想定
    str match {
      case _ => {
        if (isFirst) {
        isFirst = false
        } else {
        println(s"echo $str")
        println(s"EOS")
        }
        io(scala.io.StdIn.readLine())
    }
    }
 }
}

javaにPathを通して次のように使います

Option Explicit
Sub Test()
    Dim operator As New JarOperator
    operator.SetJarPath ("ShellTest-assembly-0.1.jar")
    Debug.Print operator.AquireStdOut("うさぎ")
    Debug.Print operator.AquireStdOut("おいし")
    Debug.Print operator.AquireStdOut("かのやま")
    Set operator = Nothing
End Sub

出力

echo うさぎ
echo おいし
echo かのやま

ScalaでJDBCのレコードを取り出す話

JDBC_Scalaメモ

ScalaからJDBC経由でMySQLにつなげた時の健忘録

まずはconnを確立

chatacterEncodingとTimezoneを伝えないと怒られる。SSLは使わないことを明示しないと怒られる。

// OperateJDBC.scala

import java.sql._  // これだとArray使えないので注意
object OperateJDBC {

  val driver = "com.mysql.cj.jdbc.Driver"
  Class.forName(driver)
  val url = "jdbc:mysql://localhost:3306/sakila" +
    "?characterEncoding=UTF-8&" +
    "serverTimezone=JST&" +
    "useSSL=false&" +
    "requireSSL=false"
  val conn = DriverManager.getConnection(url, ___, ___)
}

SELECTからとりだす

データは以下の通り

actor_ID first_name
1 PENELOPE
2 NICK
3 ED
4 JENNIFER
5 JOHNNY

まずはこんな感じでベタに実装してみる。

// OperateJDBC.scala

  // mapper。とりあえずSMALLINTだけ。
  def patternMatchObj(obj: Object, cName: String, cTypeName: String)
: (String, Any) = {
    (obj, cName, cTypeName) match {
      case (Some(o), cname, "SMALLINT UNSIGNED") =>
        cname -> o.toString.toInt
      case (Some(o), cname, _) => 
        cname -> o.toString
      case (None, cname, _) => 
        cname -> None
    }
  }

  def select(sql: String): Seq[Map[String, Any]] = {
    val stmt = conn.createStatement()
    stmt.execute(sql)
    val rs: ResultSet = stmt.getResultSet
    val md: ResultSetMetaData = rs.getMetaData
    val colCount: Int = md.getColumnCount
    val colName: Seq[String] = (1 to colCount)
      .map(md.getColumnName)
    val colTypeName: Seq[String] = (1 to colCount)
      .map(md.getColumnTypeName)

    var ret: Seq[Map[String, Any]] = Seq()
    while (rs.next()) {
      ret = ret :+ (1 to colCount)
        .map(n => Option(rs.getObject(n)))
        .zipWithIndex
        .map(t => patternMatchObj(t._1, colName(t._2), colTypeName(t._2)))
        .toMap
    }
    rs.close()
    stmt.close()

    ret
  }

テスト用コードで動かす

// TestJDBC.scala
object TestJDBC {
  def main(args: Array[String]): Unit = {
    val ret = OperateJDBC
      .select("SELECT actor_id, first_name FROM actor WHERE actor_id BETWEEN 1 AND 5")
    ret.toString.replaceAll("\\),", "),\r\n").tap(println)
  }

  implicit class RichObj[T](obj:T){
      def tap[U](f: T => U):T = {f(obj);obj;}
    }
}

出力

List(Map(actor_id -> 1, first_name -> PENELOPE),
 Map(actor_id -> 2, first_name -> NICK),
 Map(actor_id -> 3, first_name -> ED),
 Map(actor_id -> 4, first_name -> JENNIFER),
 Map(actor_id -> 5, first_name -> JOHNNY))

takeWhileを使ったパターン

varとか使っていてScala警察におこられそうなので、以下を参考にして実装

http://kmizu.hatenablog.com/entry/20121128/1354115941

  def select(sql: String):Seq[Map[String, Any]] = {
    val stmt = conn.createStatement()
    stmt.execute(sql)
    val rs: ResultSet = stmt.getResultSet
    val md: ResultSetMetaData = rs.getMetaData
    val colCount: Int = md.getColumnCount
    val colName: Seq[String] = (1 to colCount).map(md.getColumnName)
    val colTypeName: Seq[String] = (1 to colCount).map(md.getColumnTypeName)

    Iterator
      .continually{
        (1 to colCount)
          .map(n => Option(rs.getObject(n)))
          .zipWithIndex
          .map(t => patternMatchObj(t._1, colName(t._2), colTypeName(t._2)))
          .toMap
      }
      .takeWhile(x => rs.next())
      .toSeq
  }

出力。

Exception in thread "main" java.sql.SQLException: Before start of result set

多分takeWhilers.next()する前に判定しているので例外が出る。最初に判定するwhileにしたいけど方法が分からない。

Iterator.continuallyってなんだ

APIDocumentから引用。無限長Iteratorを返すらしい。

def continuallyA: Iterator[A] Creates an infinite-length iterator returning the results of evaluating an > expression.

ぐぐる

無能なので有能な先例をしらべる。

https://stackoverflow.com/questions/9636545/treating-an-sql-resultset-like-a-scala-stream

無名クラスを使ってIteratorのhasNextとnextをoverrideする方法があるらしい。今回だと以下のようになる。

new Iterator[Map[String, Any]] {
    override def hasNext: Boolean = rs.next()
    override def next(): Map[String, Any] = {
    (1 to colCount)
        .map(n => Option(rs.getObject(n)))
        .zipWithIndex
        .map(t => patternMatchObj(t._1, colName(t._2), colTypeName(t._2)))
        .toMap
    }
}.toStream

IteratorToListなんかでimmutableにすると、hasNext=>next()=>hasNext=>next()=>...と呼びだされ、hasNext == falseの時に止まる。

Iterator継承パターン

最終的にこうなった。

val ret = new Iterator[Map[String, Any]] {
    override def hasNext: Boolean = rs.next()
    override def next(): Map[String, Any] = {
    (1 to colCount)
        .map(n => Option(rs.getObject(n)))
        .zipWithIndex
        .map(t => patternMatchObj(t._1, colName(t._2), colTypeName(t._2)))
        .toMap
    }
}.toList
rs.close()
stmt.close()
ret

めでたしめでたし。

List(Map(actor_id -> 1, first_name -> PENELOPE),
 Map(actor_id -> 2, first_name -> NICK),
 Map(actor_id -> 3, first_name -> ED),
 Map(actor_id -> 4, first_name -> JENNIFER),
 Map(actor_id -> 5, first_name -> JOHNNY))

WindowsのIntelliJのScalaConsoleで文字化けする話

やること

起動/デバック構成のVMオプションに-Dfile.encoding=MS932を入れる。

f:id:usagisagi:20180421000351p:plain

winのコンソールはMS932を介しているからだと思います。

f:id:usagisagi:20180421000553p:plain

文字コードは悪い文明。いやほんとに。

ちなみに

Javaと違ってMainクラスはなく、ObjectにしないとHelloWorldできない。

object Sample {
  def main(args: Array[String]): Unit = {
    println("こんにちわ")
  }
}