NLP

学習したことを記録しています

逆求人フェスティバルに行ってきた話

2018/5/26に株式会社ジースタイラスさんが主催する逆求人フェスティバルに参加させていただきました。逆求人

f:id:hayan10:20180527180927j:plain

逆求人フェスティバルとは

逆求人フェスティバルとは会社説明会と同じようなもので企業と学生が集まり話し合う場ですが、通常の会社説明会違う点は自分がブースに立っていて企業側からブースに来ていただきPRをするようなイベントです。

参加した経緯

参加した経緯は、大学側からに逆求人に関するメールをいただいて、そのメールに書かれていた参加する企業がどれも有名どころだったので安直に応募しました。実際に1対1で話せる機会ってあんまりないなと思ったのもあります。

イベントの流れ

流れは1ターム25分間の企業と話す機会が与えられその中で5分間のPRプレゼンと残りの時間をフリートークとして色々聞いたり、聞かれたりします。それを8ターム(8社分)行いました。正直最後の方は疲れて適当なプレゼンになってかも。。 今回の参加した逆求人フェスティバルは東京で行われ、参加した学生は全部で16人、ほとんどが M1の人でした。どの学生も有名な大学で驚きましたがよく見るとNaist生が3人と一番の勢力で少し安心しました。(笑)

プレゼンに関して

あらかじめプレゼンの内容や自分の強みや企業に聞きたいことジースタイラスの高橋さんにメンターとしてアドバイスをいただいていたので自分がどんなこと人間であるかを伝えられたと思ってます(多分)。高橋さんはその道のプロともあって、人のことを引き出すのが上手だなーと思いました。感謝しています。多分、自分の長所や短所を自分で発見するのは難しくて客観的に評価してくれる人がいないとPRを考えるの一苦労、、。就活生はPRをよく書くと思いますが、一人で考えずに友達やキャリア支援室の方に客観的な意見を言ってもらって、自分を引き出してもらうのがいいと思います。自分では気づかない長所が見つかりますし人に評価してもらったことはプレゼンする時に自信を持ってアピールできると思います。

感想と気づいたこと

1. 8社の相違点と共通点

1タームはガチガチに緊張していて、しっかり挨拶できないし、目を合わせられないしで人間として終わってましたが、回数を重ねるごとに緊張もほぐれてリラックスした状態で話せるようになりました。8社(インフラ、自然言語処理機械学習系の会社のエンジニア)と話して感じたことは8社とも重視している点が違い求める人材も違いました。何をやりたいかを重視する企業、スピード感を重視する企業(スピード感とは向上心みたいなので新卒入社2,3年でリーダーとしてやって行きたいかみたいなの)、社内の輪を重視する企業、R&Dまで全部できるような人材などとバラバラでした。共通してる部分ではエンジニアの職全般に言えるかもしれませんが、多様な人がいて、上下関係のない(少ない)フラットな環境で働けるということだと思います。入社して2年目でリーダーを任され、上司を引っ張っていくこともあるそうです。実力主義なところもあるかも。

2. エンジニア→マネージャー

自分が聞きたかった「エンジニアリングとマネージメントの行き来」についても色々聞けたので共有します(共有はすごく大事と最近気づきました)。自分が会社に入った後の懸念事項はエンジニアとしてのバリバリ働いて10年経ってもエンジニアとして会社に貢献できるかどうかみたいなところで、つまり流れがはやいIT業界では新しいことに対する適用力は若者に劣るので年老いたら窓際族になることを懸念していました。実際自分の親戚にはそういった方がいるので心配でした。入社してから10,15年経った人はどのような活躍をしているのか?と尋ねたところ、大きく分けて3種類に分かれるそうです。

  • エキスパート:その道のエンジニアとしてバリバリ活躍

  • プレイングマメージャー:エンジニアの仕事とマネージメントの仕事を行う(両立)

  • マネージャー:がっつりマネージメントを行う。

プレイングマネージャーというのがあることを初めて知りました。エンジニアサイドの意見を持ったマネージメントをすることはとてもエンジニアにとって助かると思っているのでチャレンジしてみたいですね。企業によってこのエンンジとマネージャーの行き来のしやすさが違うのでその辺は実際にエンジニアからマネージャーになった人に聞かないと分からないかもしれないです。説明会にきている企業の人はそういう人が多いと思うけど。

3. 高専は強い

今回強く感じたことは高専出身(の他大学に編入した人)は強いということ。やはり企業側にPRのプレゼンするとなると実績があるかないかで印象が全然違うと思いました。自分は実績や製作物などがあるわけではないのでどうしても説得力がないプレゼンになってしまいました。(あるのは査読付き国内学会発表だけ)それに比べて高専で5年かけて技術を積み複数の実績や製作物がある人は説得力が違います。参加してた東大生3人が口を揃えて高専出身にはかなわんと言ってました。技術的な差は少しは埋めれても実績の差を埋めるのは多くの時間が必要だと思ってます。論文や製作物は1年かけてやる印象なので大変。手っ取り早く結果が出て実績として企業側にPRできるのはないのかと高専出身の人にきたところ、ハッカソン、アイディアソン、競技プログラミングなどがあるそうです。この辺の言葉は自分もNaistにきてから良く聞くようになった言葉でなんなのかはググってください。競技プログラミングに関してはレートによって格付けされるんですが企業の応募項目にそのランクが一定以上ないと受けられないこともあるくらい、競技プログラミングは最近重視されています。あとは、IT系のアルバイト経験やインターン経験もあるとないとでは違う印象でした。
積み上げた実績はTwitter,Blog,Githubなどにまとめて記載することによって企業に自分のことを良く知ってもらえたり説明できなかった部分をTwitter,Blog,Githubを通して理解してもらえるので良いと思いました。実績を書き込んでいのが楽しくてモチベにもつながると思います。

まとめ

社会人はすごい()

懇親会

逆求人フェスティバルの後に参加した学生と高橋さんで懇親会をしましたが、お互い研究 の話ばかりでお酒があまり進みませんでした(笑)

研究室のBossがサンタクロースと見分けがつかないので機械学習で自動判定させてみた

ふと寝る前に思ったことがある。

「うちの研究室のBoss(教授)サンタクロースじゃね?」

f:id:hayan10:20170829191815p:plain

↑Boss

   f:id:hayan10:20170829192953j:plain    f:id:hayan10:20170829193810j:plain

       ↑サンタクロース

いや絶対、副業でサンタクロースやってるでしょ!!

赤い服と帽子したら完全にサンタクロース

Bossが研究室に入ってきたらサンタクロースだと思ってしまい、クリスマス気分となってしますので全然研究が進まない、、、

これではダメだと思ってBossとサンタクロースを機械学習を用いて見分けることにした。

Bossの学習用のデータは研究室にたくさん写真があったのでBossの顔だけ抽出して使用

サンタクロースの学習用のデータはGoogleの画像検索から拾ってきた

Bossとサンタクロースだけでは味気ないのでカーネルさんも混ぜてあげた

f:id:hayan10:20170829195824j:plain

Bossデータ

f:id:hayan10:20170829215633p:plain

サンタクロースデータ

f:id:hayan10:20170829215635p:plain

カーネルデータ

f:id:hayan10:20170829215637p:plain

train用がそれぞれ25枚づつでtest用が8枚用意しました。

Bossの写真があんまりなくて学習が不安…

コードはこんな感じ こちらを参考にさせていただきました

http://qiita.com/hiroeorz@github/items/2fbb3b8d12b0e20f0384#_reference-99be2aef3ed42fdd155a

from keras.models import Sequential
from keras.layers import Activation, Dense, Dropout, Convolution2D, Flatten, MaxPooling2D
from keras.utils.np_utils import to_categorical
from keras.optimizers import Adagrad
from keras.optimizers import Adam
import numpy as np
from PIL import Image
import os

image_list = []
label_list = []

for dir in os.listdir("data/train"):
    if dir == ".DS_Store":
        continue

    dir1 = "data/train/" + dir 
    label = 0

    if dir == "boss":    
        label = 0
    elif dir == "santa":
        label = 1
    elif dir == "colonel":
        label = 2

    for file in os.listdir(dir1):
        if file != ".DS_Store":
            label_list.append(label)
            filepath = dir1 + "/" + file
            image = np.array(Image.open(filepath).resize((100, 100)))
            print(filepath)
            image = image.transpose(2, 0, 1)
            print(image.shape)
            image_list.append(image / 255.)

image_list = np.array(image_list)

Y = to_categorical(label_list)

model = Sequential()
model.add(Convolution2D(32, 3, 3, border_mode='same', input_shape=(3, 100, 100)))
model.add(Activation("relu"))
model.add(Convolution2D(32, 3, 3))
model.add(Activation("relu"))
model.add(Convolution2D(32, 3, 3))
model.add(Activation("relu"))
model.add(MaxPooling2D(pool_size=(2, 2), border_mode=("same")))
model.add(Dropout(0.25))

model.add(Flatten())

model.add(Dense(200))
model.add(Activation("relu"))
model.add(Dropout(0.2))

model.add(Dense(200))
model.add(Activation("relu"))
model.add(Dropout(0.2))

model.add(Dense(3))
model.add(Activation("softmax"))

opt = Adam(lr=0.0001)

model.compile(loss="categorical_crossentropy", optimizer=opt, metrics=["accuracy"])
model.fit(image_list, Y, nb_epoch=1000, batch_size=25, validation_split=0.1)

total = 0.
ok_count = 0.

for dir in os.listdir("data/test"):
    if dir == ".DS_Store":
        continue

    dir1 = "data/test/" + dir 
    label = 0

    if dir == "boss":
        label = 0
    elif dir == "santa":
        label = 1
    elif dir == "colonel":
        label = 2

    for file in os.listdir(dir1):
        if file != ".DS_Store":
            label_list.append(label)
            filepath = dir1 + "/" + file
            image = np.array(Image.open(filepath).resize((100, 100)))
            print(filepath)
            image = image.transpose(2, 0, 1)
            result = model.predict_classes(np.array([image / 255.]))
            print("label:", label, "result:", result[0])

            total += 1.

            if label == result[0]:
                ok_count += 1.

print("accuracy: ", ok_count / total * 100, "%")

実際に実行すると・・

Epoch 1000/1000
25/67 [==========>...................] - ETA: 0s - loss: 9.7016e-05 - acc: 1.00067/67 [==============================] - 0s - loss: 1.8117e-04 - acc: 1.0000 - val_loss: 0.8950 - val_acc: 0.8750
data/test/colonel/index7.jpeg
1/1 [==============================] - 0s
label: 2 result: 2
data/test/colonel/index3.jpeg
1/1 [==============================] - 0s
label: 2 result: 0
data/test/colonel/index4.jpeg
1/1 [==============================] - 0s
label: 2 result: 2
data/test/colonel/index6.jpeg
1/1 [==============================] - 0s

   (省略)

label: 1 result: 1
data/test/santa/index1.jpeg
1/1 [==============================] - 0s
label: 1 result: 1
data/test/santa/index5.jpeg
1/1 [==============================] - 0s
label: 1 result: 1
data/test/santa/index0.jpeg
1/1 [==============================] - 0s
label: 1 result: 1
accuracy:  79.16666666666666 %
79.16666666666666 %

低い、、もともとのデータ数が少ないので当然といえば当然

実際の分類はこんな感じ

f:id:hayan10:20170829203427p:plain

↑判定:Boss

f:id:hayan10:20170829203713p:plain

↑判定:カーネル

f:id:hayan10:20170829210413p:plain

↑判定:Boss

f:id:hayan10:20170829210505p:plain

↑判定:カーネル

f:id:hayan10:20170829210326p:plain

↑判定:Boss

f:id:hayan10:20170829210705p:plain

↑判定:Boss

f:id:hayan10:20170829210242p:plain

↑判定:Boss

ちなみにこれ↓はBossだそうです。

f:id:hayan10:20170829211435j:plain

確かに似てる!!

Bossのデータセットが少ないので精度が低くなりました。これからは研究しながらこっそり集めたいと思います。 こんなことしてるから研究進まないんですけどね

最後に

Bossはサンタクロースよりもカーネル似でした
これらの結果から言えることは
面接官がBossならカーネルさんと思え、以上
Bossに怒られそうで怖い。。

Python3でのプログラム

自分が学習したことをメモとしてブログに残していこうと思います。

目次

環境

Ubuntu 16.0.4
python 3.6

class


C言語を習っていたので関数やif文などは飛ばし、pythonならではであるclassの学習から行います。

Pythonオブジェクト指向プログラミングをサポートしている言語です。

そのためにはクラスを定義、作成することが必要です。

オブジェクト指向についてはこちらのブログがとても分かりやすかったので載せておきます。

クラス、インスタンス、メゾットなどの専門用語の説明も書いてあります。 tdak.hateblo.jp

まずは、どのようなプログラムになるのか見ていきましょう。

class Man:
    def __init__(self,name):
        self.name = name
        print("Initialized!")

    def hello(self):
            print("Hello "+self.name +"!")

    def goodbye(self):
        print("Good-bye "+self.name +"!")

m = Man("David")
m.hello()
m.goodbye()

上から見ていくとまずは Pythonではクラスの定義にclass文を使用します。class文を使った定義の仕方は以下のようになります。

class クラス名:

その下に一段落インデントを入れてクラスの役割つまりメゾットやコンストラクタを定義していきます。

メゾット

class クラス名:
    def メソッド名(self):
        #メソッドの定義

コンストラクタを定義するには「init」という名前のメソッドを作成します。

コンストラクタ

class クラス名:
    def __init__(self, 引数1, 引数2, ….):
        #コンストラクタの定義

コンスタンスの定義文には

self.name = name

のようにクラスが持つ「name」変数に引数を格納します。

そしてこのクラスのインスタンス生成やメゾットの呼び出し方は下記のように行います。

m = Man("David")
m.hello()
m.goodbye()

ここではDavidがnameの変数に渡され、インスタンスを生成します。

そしてメゾットを呼び出すにはインスタンス.メソッド名()とすることでメゾットが実行されます。

このプログラムの実行例はこのようになります。

Initialized!
Hello David!
Good-bye David!

attention機構を持つLSTMを用いた含意関係認識

目次

今回はattention機構を持つLSTMを用いて含意認識を行います。

環境はこんな感じ

Ubuntu 16.04
python 2.7
tensorflow-gpu 1.2.0

今回のモデルはこれです。 f:id:hayan10:20170724144135p:plain

参考論文は[REASONING ABOUT ENTAILMENT WITH NEURAL ATTENTION] https://arxiv.org/pdf/1509.06664.pdf


実行データのダウンロード

githubにてデータのダウンロードをします。

ここから

GitHub - borelien/entailment-neural-attention-lstm-tf: (arXiv:1509.06664) Reasoning about Entailment with Neural Attention

右上の緑のClone or Download からダウンロードしてください。

Dataset

今回の含意認識に使うデータセットスタンフォード大学が提供する

The Stanford Natural Language Inference (SNLI) Corpusです。

                コーパスの例

Text Judgments Hypothesis
A man inspects the uniform of a figure in some East Asian country. contradiction The man is sleeping
An older and younger man smiling. neutral Two men are smiling and laughing at the cats playing on the floor.
A black race car starts up in front of a crowd of people. contradiction A man is driving down a lonely road.
A soccer game with multiple males playing. entailment Some men are playing a sport.
A smiling costumed woman is holding an umbrella. neutral A happy woman in a fairy costume holds an umbrella.

分類はentailment,neutral,contradictionの3種類にわけられ、5人の人間の意見による多数決によってラベル付けされています。

データの規模は57万データあり、すべての文はパースされています。

ダウンロードは下記のURLから

http://nlp.stanford.edu/projects/snli/snli_1.0.zip

ダウンロードしたzipファイルを解凍すると、_MACOSXsnli_1.0のファイルがあるのでsnli_1.0のフォルダの中身をdata/datasetに入れる。 (.DS_store,Icon^M,README.txtは入れなくてもOK)

Word2Vect

Word2Vectによって学習済みの単語の分散表現のデータをダウンロードします。

今回はGoogleNewsをもとに学習したデータを使います。

下記からダウンロード

GoogleNews

ダウンロードできない人は下記からGoogleNews-vectors-negative300.binだけをダウンロードする。

GitHub - mmihaltz/word2vec-GoogleNews-vectors: word2vec Google News model

ダウンロードしたGoogleNews-vectors-negative300.bindataの中に入れる。

プログラムの変更

githubでダウンロードしたプログラムでは python 2.7 tensorflow-gpu 1.2.0の環境で実行できないので プログラムの中身を変更します。

事前に変更しておいたプログラムがありますので下記からすべてダウンロードし pythonのファイルの中に上書き保存してください。

python - Google ドライブ

プログラム実行

実際に動かして行きましょう。まずはterminalにてpythonのあるディレクトリへ移動します。

いくつかのオプションを閲覧するときは下記を実行してください。

python main.py --help

トレーニングを開始するには

python main.py --train

すると、、、 こんな感じでトレーニングが開始します。 f:id:hayan10:20170724162034p:plain

ちなみにデフォルトでのハイパーパラメータはこのようになっています。

learning_rate = 0.001
weight_decay = 0.
batch_size_train = 24
num_epochs = 45
sequence_length = 20
embedding_dim = 300
num_units = 100

UbuntuでPyCharmのインストール

PyCharmのインストー

まずは公式サイトからPyCharmをダウンロードします。 今回はcommunityエディションを用います。 f:id:hayan10:20170718162951p:plain

ダウンロードしたディレクトリでファイルを解凍します。ディレクトリが分からない場合は、右上の下矢印ボタンをクリックしディレクトを見たいファイルの右隣にあるフォルダボタンをクリックすると、該当のファイルが置かれたディレクトリに飛びます。

tar -zxvf pycharm-community-2017.1.5.gz

解凍が終わったら解凍されたファルダがあるディレクトリにて 下記のコマンドでPyCharmが実行されます。

bash pycharm-community-2017.1.5/bin/pycharm.sh 

実行画面 f:id:hayan10:20170718163358p:plain

毎回指定のディレクトリにてコマンドを実行するのは面倒なのでホームディレクトリにpycharm-community-2017.1.5を置くといいでしょう。

GPUの使用状況を知る(Ubuntu16, Cuda8)

Ubuntu16 Cuda8の環境でGUP使用率確認方法

GPUの使用率を確認するためにはterminal上で以下を実行する。

$ nvidia-smi

するとこのような画面が出る。

f:id:hayan10:20170718110927p:plain 右端の%のところがGPUの使用率。

TensorFlowをインストール (Linux,Mac OS)

TensorFlowをインストール (Linux,Mac OS)

pipでTensorFlowをインストー

LinuxMac OSでもpipを使ってtensorflowをダウンロードが可能です。
まず、pipのバージョンが8.1以上である必要があるので、まずは念のためpipを最新バージョンにアップグレードしておこう。

terminal
$ pip install --upgrade pip

そのあとはCPUとGPUとで別のtensorflowをダウンロードする。

CPU版

terminal
$ pip install tensorflow

GPU

terminal
$ pip install tensorflow-gpu

インストールできたら動作の確認をしましょう。
きちんとインストールされているか確かめるために、Pythonから動作確認をしてみよう。

terminal
$ python
>> import tensorflow as tf
>> hello = tf.constant('Hello, TensorFlow!')
>> sess = tf.Session()
>> print(sess.run(hello))
b'Hello, TensorFlow!'

何も問題が無ければ、無事にコンソールにb'Hello, TensorFlow!'と表示されたはずです。