欲しい物




「何か欲しい物、ある?」







数年前の10月の中頃に、同じ部活の女の子(パートリーダー)からメールでこう尋ねられた。









「特に無いけど。どうして?」








「もう過ぎちゃったけど、誕プレをあげようかなと思って」








どうやら、誕生日(私の誕生日は10月のはじめの方)を祝ってくれるらしい。







私は冗談のつもりで、






「……強いていうなら、愛が欲しいかな(笑)」






と送った。いや、最後の(笑)は送ってない。








そしたら、なんか付き合うことになってしまった。







びっくり。








その子に全然興味なかったけど。








でも、その子のテンションがすごく上がってたから、悪い気はしなかった。








私の今までの人生で、こんなにも人に喜ばれたことがなかったからね。








そして迎えた最初の彼女の誕生日。







私は何もしなかった。








そして迎えた最初のクリスマス。















紫色が好きだった彼女は、私に紫色のマフラーをくれた。








私は何もあげなかった。












その子にあんまり興味なかったから。








そして迎えた最初のバレンタインデー。








彼女は手作りのお菓子を作ってくれた。








そして迎えた最初のホワイトデー。








何をしたかは覚えてない。









いつからか彼女は私と二人きりになるのを避けるようになっていた。








もちろん練習に支障がでてしまう。









4月頃には、部活にもあまり来なくなっていた。








そしていつのまにか部活をやめていた。








私たちのバンドは、唯一の戦力ともいえる存在を失った。








いつのまにか私がパートリーダーになっていた。








残された私たちは、彼女が抜けた分の穴を埋めるのに必死だった。







でも全然埋められなかった。







その穴はあまりにも大きくて。







そして迎えた支部大会(全国大会の前の大会)本番。








結局満足のいく演奏ができないまま、私たちの最後の夏は終わった。








僅差だった。








もしも彼女が部活をやめていなかったら?








もしも私と彼女の関係が良好だったら?








まとめ





彼女には誕生日プレゼントをあげよう。







さもなければ毎年12月9日という日付を見てもやもやした気分になるかもしれない。

broadcast系男子

櫻井研では、以前、「list内包表記系男子」という言葉が流行りましたね。
しかし、list内包表記に書き換えることよる実行時間削減効果は、他の高速化テクニックに比べてそこまで効果が大きいものではありません。

ところで、Pythonを使って科学技術計算をする人々の間ではこんな言葉が流行っているのをご存知ですか?
broadcast系男子
broadcastとは、numpyで使われる配列の演算の方法です。
さっそく具体例を見てみましょう。

例1
>>> import numpy as np 
>>> a=np.arange(5)
>>> a
array([0, 1, 2, 3, 4])
>>> a*5
array([0, 5, 10, 15, 20])

「え、普通じゃん」と思う方もいらっしゃることでしょう。
(初歩的な質問ですが、aがnumpyの配列ではなくPythonのリストである場合、a*5はどうなるかわかりますよね?)

それでは別の具体例を見てみましょう。

例2
>>> a=np.array([[10, 20], [30, 40]])
>>> b=np.array([1, 2])
>>> a+b
array([[11, 22],
       [31, 42]])

aとbの配列の次元(以下shapeと呼ぶ)は一致しませんが、足し算ができていますね。
これがbroadcastするということなのです。

次に少しだけ違う例を見てみましょう。

例3
>>> a=np.array([[10, 20], [30, 40]])
>>> b=np.array([[1], [2]])
>>> a+b
array([[11, 21],
       [32, 42]])

例2ではb.shapeは(2,)でしたが、例3ではa.shapeは(2, 1)になっていますよね。
小さな違いが大きな差を生むのです。


実は、broadcastを使うと、大きな行列(あるいはテンソル)を少ない計算量で生成することができることがあるのです。

問題

# この配列を生成
[[0,   4,   8,   12,  16,  20,  24,  28,  32,  36],
 [1,   5,   9,   13,  17,  21,  25,  29,  33,  37],
 [2,   6,   10,  14,  18,  22,  26,  30,  34,  38],
 [3,   7,   11,  15,  19,  23,  27,  31,  35,  39],
 [40,  44,  48,  52,  56,  60,  64,  68,  72,  76],
 [41,  45,  49,  53,  57,  61,  65,  69,  73,  77],
 [42,  46,  50,  54,  58,  62,  66,  70,  74,  78],
 [43,  47,  51,  55,  59,  63,  67,  71,  75,  79],
 [80,  84,  88,  92,  96,  100, 104, 108, 112, 116],
 [81,  85,  89,  93,  97,  101, 105, 109, 113, 117],
 [82,  86,  90,  94,  98,  102, 106, 110, 114, 118],
 [83,  87,  91,  95,  99,  103, 107, 111, 115, 119],
 [120, 124, 128, 132, 136, 140, 144, 148, 152, 156],
 [121, 125, 129, 133, 137, 141, 145, 149, 153, 157],
 [122, 126, 130, 134, 138, 142, 146, 150, 154, 158],
 [123, 127, 131, 135, 139, 143, 147, 151, 155, 159],
 [160, 164, 168, 172, 176, 180, 184, 188, 192, 196],
 [161, 165, 169, 173, 177, 181, 185, 189, 193, 197],
 [162, 166, 170, 174, 178, 182, 186, 190, 194, 198],
 [163, 167, 171, 175, 179, 183, 187, 191, 195, 199]]

解答例

ここでは4つの解法を用意してみました。
それでは早速ご覧ください。

import numpy as np


# リスト内包表記を使わない
def func1(step=4, dim=10, n=200, length=5):
    indices1 = []
    for l in range(length):
        for s in range(step):
            index = range(l * step * dim + s, (l + 1) * step * dim + s, step)
            indices1.append(index)
    return(indices1)


# リスト内包表記を使う
def func2(step=4, dim=10, n=200, length=5):
    indices2 = [range(l * step * dim + s, (l + 1) * step * dim + s, step)
                for l in range(length) for s in range(step)]
    return(indices2)


# ブロードキャストを使う その1
def func3(step=4, dim=10, n=200, length=5):
    l = np.arange(0, n, step * dim)
    ll = l.reshape(length, 1)
    s = np.arange(step)
    ss = s.reshape(1, step)
    ls = (ll + ss).reshape(length * step, 1)  # ここでブロードキャスト
    i = np.arange(0, dim * step, step)
    ii = x.reshape(1, dim)
    return(ls + ii)                   # ここでもう一度ブロードキャスト


# ブロードキャストを使う その2
def func4(step=4, dim=10, n=200, length=5):
    x = np.arange(0, dim * step, step)
    y = np.arange(0, n, step * dim)
    z = np.arange(step)
    xx = x.reshape(1, 1, dim)
    yy = y.reshape(length, 1, 1)
    zz = z.reshape(1, step, 1)
    indices = xx + yy + zz	              # ここでブロードキャスト
    return(indices.reshape(n / dim, dim))

結果

今回は、jupyter notebook のマジックコマンドの1つである timeitを用いて時間を測定しました。

%timeit func1()
10000 loops, best of 3: 71.4 µs per loop

%timeit func2()
10000 loops, best of 3: 70.7 µs per loop

%timeit func3()
10000 loops, best of 3: 46.6 µs per loop

%timeit func4()
10000 loops, best of 3: 44.5 µs per loop

結構速くなっていますね。
実は、この高速化は行列が大きいほど効果が大きいのです。
step=40, dim=100, n=200000, length=50にして(要素数が1000倍になった)実行時間を測定してみましょう。

%timeit func1(40,100,200000,50)
100 loops, best of 3: 13 ms per loop

%timeit func2(40,100,200000,50)
100 loops, best of 3: 10.1 ms per loop

%timeit func3(40,100,200000,50)
1000 loops, best of 3: 783 µs per loop

%timeit func4(40,100,200000,50)
1000 loops, best of 3: 788 µs per loop

10倍以上高速化できましたね。

結論

broadcastを使うと良い。
broadcast系男子がいまアツい。

質疑応答

Q. めんどくさいんだけど?
A. 慣れれば簡単です。

Q. numpyを使ったから速いってだけなんじゃないの?
A. numpyをテキトーに使っても、2倍程度しか速くなりませんでした。
broadcastと上手く組み合わせることにより10倍以上高速化することができます。

Q. 解答例が意味分かんないんだけど?
A. 各変数に何が格納されているかをぜひ自分で確かめてみてください。

Q. 足し算でしか使えないの?
A. 引き算、掛け算、割り算、その他numpyが対応する二項演算でも使うことができます。

Q. numpy特有のテクニックなの?
A. 若干仕様が異なりますが、Mathematicaでも使えます。

ため息

葵です

こんにちは

 

高杉晋作についても触れてしまったし、

書くことが思いつかないので、趣味のピアノについてです~

 

クラシックといっても広くて、いろいろあります。

その中で、私が一番好きな曲について書きます。

 

リストの「ため息」です

もともと古典派とかよりロマン派の方が好きなのですが、この曲の何が良いかと言われると言葉にはできないけど、綺麗な曲が好きです。

ずーっとこの曲に憧れて、大学生になってから弾きました。

 

簡単に曲についてまとめると、(Wikipediaを参考に…)

リストは1811年生まれです。ショパンが生まれた次の年ですね。

2011年(私が大学1年のとき)に生誕200周年で、その年の三田祭でリストを弾きました。(「2つの演奏会用練習曲」の2番の小人の踊り)

 

リストが作った「3つの演奏会用練習曲」の3番がため息です。

リストは指が長くて、え、これ片手で弾くのかよみたいな楽譜が多いけど、(ラ・カンパネラとか)

その中では弾きやすい気がしてます。右手と左手をずっと交差しながら弾く曲なんです。

リストは練習曲として作ったようですが、それこそため息をついてしまうくらい美しい曲です。

 

私がこの曲を好きになったきっかけは、フジ子・ヘミングの演奏です。

この人が送ってきた波乱の人生が、すべての演奏に出ている気がします。

 

www.youtube.com

 

 

ちなみに最近よく出ている辻井伸行さんの演奏より好きです。

辻井さんはテクニックが神だけど、深みが上の演奏より劣ってると思ってます。

 

辻井伸行 Nobuyuki Tsujii performsA sigh by Franz Liszt「ため息」フランツリスト_土豆_高清视频在线观看

 

ため息が出るくらい素敵な演奏、してみたいですね

 

おわり

 

まだLINE使ってるの?

今日のテーマは?

僕の日記も4記事目です。クリスマス10日前ということで、街を歩けば山下達郎竹内まりやの名曲が聴こえてきます。どうやら櫻井研クリスマスパーティの計画も水面下で進んでいるようで、今年は楽しいクリスマスになりそうです。そういえばB3歓迎会もあるし、26日には僕達の代の代表が研究室に遊びに来る(!?)し、12月は予定がたくさん。そんなとき、コミュニケーションツールとしておすすめなのがslackです。今日はslackの紹介記事を書こうと思います。

LINEじゃダメなの?

ダメです。常日頃から口癖のようにLINEはクソと言っている僕ですが、このLINE嫌いはビートルズミスチルと違って明確な理由のある本当に嫌いな類です。本題とズレるので、ここでは箇条書きでLINEが如何にダメか見てみます。

  • マルチアカウント非対応
  • セキュリティ面に大きな不安
  • Linuxネイティブアプリ非対応(最近Chormeアプリが出たことによりほぼ改善)

LINEとはここが違う

LINEの欠点がslackではどのように改善されているか見てみましょう。

  • マルチアカウント対応

複数のアカウントを作り、1端末から複数アカウントにログインすることができます。僕のような端末マニアも安心の仕様です。

  • メインは企業用で安心のセキュリティ

LINEのようにプライベートというよりは企業向けの色が強く、当然セキュリティも信頼がおけるものです。

Android, iOS, Windows, Mac, Ubuntu, Fedoraに対応しています。また、Chromeアプリやブラウザ版もあるため、ほとんどのプラットフォームで利用できます。

slackのいいところ

  • ファイルの保存期限がない(10000件まで)
  • グループ(次に説明するチャンネル)に後から入っても過去の会話が見られる
  • チーム(例えば櫻井研とか)の下にチャンネル(例えばB4輪講/M1輪講/情報意味論とか)があり、各メンバーはそれぞれ自分が必要だと思うチャンネルに入ることができる
  • botを作ることができる
  • UIがおしゃれ(と言われることが多い?)
  • and more...

最後に

これを読んでいる皆さんは、社会に出てからslackを使うことも多いと思うので、今のうちに慣れておくという意味でも、導入してみませんか?ダウンロードはこちらから。

Download Apps | Slack

アジア旅行記

こんにちは。B4中村です。

布団から出るのが億劫になる季節、毎日寒いですね。特に朝は・・

何か自分なりの話題をと考えたのですが、なかなか書くネタが見つからず。。
そこで、何か自分に関係する話題をということで、趣味(?)の旅行に関連した記事を書こうと思います。
昔から旅行が好きで、特にアジアの国々を旅行することに興味があり、これまで4カ国、マレーシア・韓国・ベトナム・中国を旅行してきました。本格的なバックパッカーの方からすれば、全然少ないですが・・

このうち、滞在期間の長かったマレーシア韓国中国について、第一印象というか、自分が実際に行って、見て、感じたコトを書いていこうと思います。

なお、これらは完全に僕自身の主観と実感であるため、不適切な点があれば、そこはご容赦を・・・

 

では

 

1カ国目 マレーシア(2010年、1週間)
第一印象は、「怒涛の建設ラッシュ」と、「市場が自由過ぎて面白い」

f:id:d-higurashi:20151212223913j:plain

当時はまさに発展真っ盛りで、至る所で高層ビルが建設中でした。ほんとうに、あっちもこっちも「工事中」。重機の音が四方八方から飛び込んできます。
それだけでなく、古い家屋は容赦なく取り壊されていってました。強制的な立ち退きをがんがん迫っていたのでしょうか。
高校生ながら、「ちょっと無理やりすぎなのでは?」と思ってしまいました。

そして、多分これは初めてのアジア旅行だったからかもしれないのですが、自由奔放な市場の雰囲気が、自分にとって強烈な印象でした。
生の肉や魚が気温35度の中で、冷蔵もされずに露店売り。しかも、日本では普通見ないような、鶏の頭や豚足、食べれるものはなんでもかんでも売っていました。
見たこともない極彩色のど派手な野菜や果物、なんだかよく分からない謎の生物の肉も売られていて、市場全体、半端ないカオス(笑)
ニオイや衛生状態は筆舌に尽し難いものがありましたが、しかし、なぜかこう、その自由なマーケットの雰囲気に、非常にワクワクしてました。
値札はあってないようなもので、ほとんど交渉で売り買い、日用品から生鮮食品、それも「これ、ほんとに食べ物?」というものまで、なんでもかんでも売っている市場。
厳密で画一的な日本のスーパーとの対比はすごかったですが、それぞれの良さをしみじみ実感した旅行でした。

 

2カ国目 韓国(2014年、1週間)
第一印象は、「超、ソウル一極集中」と、「アクティブな人が非常に多い」

f:id:d-higurashi:20151212222059j:plain
ソウルの集合住宅をご存じの方がいらっしゃると思いますが、ソウルの集合団地は、「高層ビルの密集体」です。
金浦空港に到着する直前飛行機から見た光景なのですが、新宿の高層ビル群が至る所に乱立している状態した。
身近な例では、武蔵小杉のタワーマンションが何十棟と集まって群をなし、しかもその群があちこちにあるといった感じ。
もうほんとに、「ニョキニョキ生えている」と例えていいレベルです。
それもそのはず、ソウルの人口は、なんと韓国国内全人口の9割を占めているそうです。東京23区は全国の人口の1割ほどであり、ソウルがいかに一極集中か、身をもって実感しました。

そして、韓国で出会った人々は、みんな「アクティブ」。
常に戦闘状態のようというか、あらゆる行動に隙がありません。引き締まっているとでも例えればいいでしょうか、みんなキビキビ、テキパキ。
日本人はどこかゆったりとした雰囲気がありますが、韓国人はみんなガツガツしています。街中活気があり、パワーに溢れていました。
そういえば韓国の食事は、キムチが毎回出てくるのは当然のこと、肉料理が非常に多いことに気づきました。日本と違って、韓国は肉食文化なんですね。
もしかしたら、この肉食文化が彼らのパワーの源なのかもしれません。文字通り「肉食系」でした笑

 

3カ国目 中国(2014年、2週間)

f:id:d-higurashi:20151212223151j:plain


第一印象は、「スケール半端ない」と、「超特急の開発」
スケールが半端ないというのは、現在の中国の政策からも明らかかと思います。何十兆円というインフラ資金をドカンと投入したり、政治、外交面でも・・
このスケールの大きさは、都心部にいても実感しました。旅行で散々お世話になった中国国鉄の新幹線(日本の新幹線にそっくり!)は、まさにその代表格です。
例えば上海の新幹線駅。駅というよりはもはや空港というべき広さです。
特に、日本の東京駅の新幹線のホームの数が10本になのに対し、上海駅のそれはなんと30本!端から端に歩くだけでも一苦労。
全てのプラットフォームを使っているわけではありませんでしたが、今の中国の発展状況を考えれば、「30番線から発車」なんていうアナウンスを聞く日はそう遠くなさそうです。
また、道路に関しても例えば、片側7車線×2なんていう光景をみました。今後の発展を見据えての建設は、日本とは比較にならない規模です。
ただ、そのような怒涛のインフラ整備ラッシュではありましたが、ホントにこんなに使うのか?ちょっと過剰すぎないか?というのが正直な実感でありました。「とりあえず、ビッグに造ってしまおう」という感じというかなんというか・・

建設の規模もさることながら、旅行では、中国の「急ピッチ」な開発も実感しました。
例えば、地下鉄や新幹線では、電車からしょっちゅう工事中の光景を目の当たりにしていました。今使っている線路のすぐ隣で、何十人もの建設作業員が火花を飛び散らしながら次の線路を造っている、そしてその隣では、線路増設のための橋梁建設の真っ最中・・
マレーシアでも建設ラッシュの光景は目にしていましたが、そのレベルがまるで違います。大量の作業員と何十台もの重機が「大量投入」されている印象した。
実際、例えば中国国内の鉄道に関しては、約10年で65,000kmが開通し、2020年までに100,000kmを目標にしているとのこと。
日本は約60年で7,000~8,000km程であることを考えると、その開発スピードは半端ないです。新幹線だけに、開発スピードも「超特急」。ものすごい人・物・金の投入規模です。


以上、拙い文章ながら、マレーシア、韓国、中国を旅行したときの印象を書き連ねさせていただきました。
様々な印象や実感を経験できたこれまでの旅行ですが、3カ国のどの国にも共通していたのは、「みなぎる開発パワー」です。
物凄いスピードで追いつけ追い越せがなされている現状を目の当たりにし、非常に刺激を受けたと同時に、このままうかうかしていれば日本なぞあっという間に飲み込まれるぞという危機感をも持ちました。
しかし、彼らのパワーに圧倒こそされたものの、負けてたまるかという感情も沸々と湧き起こりました。
彼らが追いつけ追い越せを仕掛けているのなら、私たち日本人も「先を越してやる」くらいの心構えで対抗すべきだと思います。


・・・とまあ最後にカッコつけてしまいましたが・・・
「アジア旅行は超楽しい!」を皆さまに伝えたく、今回中村が記事を書かせていただきました。
少しでも興味を持っていただけたなら幸いです。
たどたどしい文章、最後まで読んでいただき、どうもありがとうございましたm(_ _)m

list内包表記系男子

たまには真面目に

櫻井研らしくたまには真面目な記事を。巷ではこんな言葉が流行っているのをご存知ですか?

list内包表記系男子

list内包表記とは、pythonの特徴的なリスト表記の方法です。具体例を見てみましょう。0から20までの偶数を要素として持つリストを作ってみます。

# リスト内包表記を使わない
range(0, 21, 2)

# リスト内包表記
[2 * i for i in range(11)]

このくらい単純な配列であれば、range関数をうまく使うことでリスト内包表記を使わなくても大丈夫です。しかし次の場合はどうでしょうか。

問題

# この配列を生成
[[0,   4,   8,   12,  16,  20,  24,  28,  32,  36],
 [1,   5,   9,   13,  17,  21,  25,  29,  33,  37],
 [2,   6,   10,  14,  18,  22,  26,  30,  34,  38],
 [3,   7,   11,  15,  19,  23,  27,  31,  35,  39],
 [40,  44,  48,  52,  56,  60,  64,  68,  72,  76],
 [41,  45,  49,  53,  57,  61,  65,  69,  73,  77],
 [42,  46,  50,  54,  58,  62,  66,  70,  74,  78],
 [43,  47,  51,  55,  59,  63,  67,  71,  75,  79],
 [80,  84,  88,  92,  96,  100, 104, 108, 112, 116],
 [81,  85,  89,  93,  97,  101, 105, 109, 113, 117],
 [82,  86,  90,  94,  98,  102, 106, 110, 114, 118],
 [83,  87,  91,  95,  99,  103, 107, 111, 115, 119],
 [120, 124, 128, 132, 136, 140, 144, 148, 152, 156],
 [121, 125, 129, 133, 137, 141, 145, 149, 153, 157],
 [122, 126, 130, 134, 138, 142, 146, 150, 154, 158],
 [123, 127, 131, 135, 139, 143, 147, 151, 155, 159],
 [160, 164, 168, 172, 176, 180, 184, 188, 192, 196],
 [161, 165, 169, 173, 177, 181, 185, 189, 193, 197],
 [162, 166, 170, 174, 178, 182, 186, 190, 194, 198],
 [163, 167, 171, 175, 179, 183, 187, 191, 195, 199]]

言葉で説明するならば、次のような2次元配列です。

  • n個の数字が重複なしで出てくる(n=200)
  • 各要素の配列はdim個(dim=10)
  • 各要素の配列の要素はstep刻みで増えていく(step=4)

これはn個の時系列データからstep刻みでデータを取って間引いたdim次元のデータを取り出すときのインデックスになります。これをコードで表すとどうなるか見てみましょう。

回答例

step = 4
dim = 10
n = 200
length = n / step / dim

# リスト内包表記を使わない
indexs = []
for l in range(length):
    for s in range(step):
        index = range(l * step * dim + s, (l + 1) * step * dim + s, step)
        indexs.append(index)

# リスト内包表記
indexs = [range(l * step * dim + s, (l + 1) * step * dim + s, step)
          for l in range(length) for s in range(step)]

どうですか。リスト内包表記では5行も必要なところ、リスト内包表記では2行で書けます。(pep8に従って途中で改行しているが、つながっているので実質1行)簡潔なコードは、デバッグするときも拡張するときも優秀です。

さらに実行時間にも影響があります。それぞれのコードを100万回繰り返したときの実行時間は以下の通りです。

リスト内包表記なし 25.2(s)
リスト内包表記あり 21.8(s)

リスト内包表記のほうが実行時間が短いです。Deep Learningでは実行時間がネックになることが多々あるため、こうした実行時間削減の工夫は重要です。

でも注意が必要

リスト内包表記は確かに短く速いコードが書けます。しかし「何を目的としたどんなコードなのか」が少し分かりにくくなっています。そのため、何回も呼び出されたり、リスト内包表記でもシンプルに書けたりするときは積極的に使うべきですが、1回しか呼び出されないしリスト内包表記だと見にくくなる場合は無理に使う必要はないと思います。for文にするかリスト内包表記にするかを一瞬で判断できるようになれば、今日から君もPythonista!