技術をかじる猫

適当に気になった技術や言語、思ったこと考えた事など。

Mac から乗り換えた:ASUS UF Dash F15 FX516PR

乗り換えて 1 週間使ったので、レビューを。

乗り換えたのはコレ。

個人的評価

Mac から乗り換えるならこれが一番コスパ良いかも?

少なくともコストパフォーマンスで乗り換え選択を行うなら、これが個人的に一番しっくりくるという結論に至った。
概ね満足できるという評価です。

  • いい点
    • GeforceRTX 3000 番台(性能は RTX 2070 以上 RTX 2070 SUPER 以下)で、ヘビーでない限りはゲーム用途として申し分ない。
    • CPU も概ね満足。11世代 Core-i7 で何が不満なんだ…
    • 16GB メモリに、1T ストレージ。普通に使うのには支障がない。
    • テンキーが無い
    • この性能でこの値段は何だ!?
  • 悪い点
    • 静音か?と言われれば疑問は残る。GPU ぶん回すとかしなければ静音。
    • ディスプレイのリフレッシュレートが 200 超えるのに、搭載 Geforece はリミッターがあるのか、144Hz 位が良いところ…(ちょい勿体ない)

因みに、スペックだけで評価を見る場合はこちらのレビューがおすすめ

ASUS TUF Dash F15 FX516PRレビュー|RTX 3070搭載ゲーミングノート|ゲーミングPCログ

満足できる人

  • X86-64 CPU が必要で、かつ Mac から手ごろな値段で代わりに使えるマシンを模索している人。
  • ミドルレンジクラスでゲームをする人。
  • 開発者など。
  • 見た目のセンスより開発しやすいことが重要と割り切れる人

おすすめできない人

  • 経理とか数字をやたら打つ人
  • インストールは DVD からでないと…というアンチオンラインストア
  • 事務系作業する人(ゲーミングPCにそもそも合わない)
  • Mac の見た目のセンスが良ーんだろーがという人

感想:なぜ Mac からの乗り換えに適してるか

Mac Book Pro 15inch 使ってた人は以下の内容に同意してくれるはずだ。

  • 分厚いPCは勘弁(DVDドライブとか邪魔。デスクトップで見ればいいし)
  • トラックパッドマウスに触ってフォーカス移動とか本気で要らない。むしろブチギレ案件
  • 15 インチ以上のディスプレイくれよ
  • メモリは 16G は必須
  • ストレージは多いに越したことはない

というもの。

残念ながら、このマシンは Mac より薄くはなく、ほかの Windows ノートよりはマシといったところ。
ではなぜおすすめできるかというと

コスパ

CPU/メモリ容量/ストレージ容量/グラボ これら合わせて 20 万ちょっとに収まるのは、コスパが良いといって差し支えない。
Asus は全体的にコスパは高め。

テンキーがない

これは経理とか一部の「数字をやたら叩くお仕事の人」には辛いかもしれないが、正直プログラマーにしてみれば利点でしかない。
むしろテンキーなんてものは邪魔でしかないと断じる。

  • ノートパソコンはそもそも面積に限界がある。
  • テンキーが入ると普通のキーはそれに押され、レイアウト上、中央から左寄りになってしまう。

さぁ、ここでプログラマーや開発者諸君の、「文字スペースを打つときに手首を置きたい」という要望があるとどうなるか?
打ちたいキーが左にずれる。なら右手首を置きたい場所には何がある…?

トラックパッドとかいう最も邪魔な機能がある

これである。

対抗馬

金に糸目を受けないという条件があるのなら、DellXPS 15 なども良いかもしれない。
比較するとこんな感じになる

  • XPS 15 の方が薄い
  • XPS 15 は 1TB ストレージを選択すると 30 万に突入する
  • それ以外の性能はおおよそ トントン

コスパを取るか薄さ(の代わりに高額)を取るか…

他の対抗馬としては

  • HP の Envy シリーズ:こちらも XPS シリーズと同じで、薄さでは勝ってるがディスク容量を求めると値段が跳ね上がる…。
  • Microsoft Surface シリーズ:メモリ 16 G以上にするなら 30 万近くになるんだ…薄いんだけどさ…
  • VAIO Z シリーズ:グラボ積んでなくていいならとてもいいかも?(個人的に TensorGPU で走らせたいので見送った)

…因みに HUAWEI の mate book シリーズは安くて薄いのだけど、米国繋がりで火中の栗感があって申し訳ないが避けた…

ニューロンの定義と、重み/バイアスの影響

ということで、ニューロンの定義とその重みやバイアスでどう影響するのかを見てみる。
影響の方向性を確認するけども、目的としては重みとバイアスで出力って変わるんだなーって理解すること。

ニューロンに使う関数

シグモイド関数は前回の通り。
まぁ 0 以上 1 以下にして返してくれる関数となっている。

import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline


def sigmoid(x):
    return 1 / (1 + np.exp(-x))

x = np.linspace(-5, 5)
y = sigmoid(x)
plt.plot(x, y)
plt.show()

f:id:white-azalea:20210221002132p:plain

ニューロン定義

で、ニューロンの定義が、活性関数を f, データを x, 重みを w, バイアスを b としたときに


\mu = \sum^{n}_{k=1}{x_k w_k} + b \\
y = f(\mu)

なので、例えば2次元のデータを食わせるとしてこんなデータを用意する

# 食わせるデータサンプル
x_1 = np.arange(-1.0, 1.0, 0.2)
x_2 = np.arange(-1.0, 1.0, 0.2)

X = np.zeros((10, 10, 2))
for i in range(10):
    for j in range(10):
        X[j][i] = np.array([x_1[i], x_2[j]])

データ的にはこんな感じになってるはず。

    X = [
        [[-1, -1],   [-0.8, -1] ...   [0.8, -1]],
        [[-1, -0.8], [-0.8, -0.8] ... [0.8, -0.8]],
        ...
    ]

なので、単純に足し合わせてヒートマップにすると

def temp():
    x = np.zeros((10, 10))
    for i in range(10):
        for j in range(10):
            x[j][i] = sum(X[j][i])
    plt.imshow(x, 'gray', vmin = -2.0, vmax = 2.0)
    plt.colorbar()
    plt.show()

temp()

f:id:white-azalea:20210222221259p:plain

見たまま黒=マイナス値 というこんな分布が出来上がる。
で、ニューロンはこうなるはず

def exec_single(w_x, w_y, bias):
    # 結果を食わせるテンポラリデータ
    z = np.zeros((10, 10))

    # x/y 軸で走査
    for i in range(10):
        for j in range(10):
            # x/y に重みを掛けて、バイアスを加える
            u = X[j][i][0] * w_x + X[j][i][1] * w_y + bias
            # その値をシグモイド関数に食わせて
            z[j][i] = sigmoid(u)
    
    # プロットする
    plt.imshow(z, 'gray', vmin = 0.0, vmax = 1.0)
    plt.colorbar()
    plt.show()

で、x, y をそのまま適用して、すべてのパラメータを 1,0 にしてみるとこんな感じ。

exec_single(w_x = 1, w_y = 1, bias = 1.0)

f:id:white-azalea:20210221002512p:plain

最小が


  u = -1 + -1 + 1.0 = -1.0 \\
  f(-1.0) = 0.2689414213699951

で座標 (0, 0) が黒く染まり


  u = 0.8 + 0.8 + 1.0 = 2.6 \\
  f(2.6) = 0.9308615796566533

ということで座標 (1, 1) (右下) になるほど白くなる。

バイアスを削ると全体の値が小さくなるので、心持ち黒くなる

exec_single(w_x = 1, w_y = 1, bias = 0)

f:id:white-azalea:20210221002649p:plain

Y 軸の重みを 0 (y 軸を評価しない)とすると、X軸だけで重みが決まるので縦線に

exec_single(w_x = 1, w_y = 0, bias = 0.5)

f:id:white-azalea:20210221002735p:plain

続きを読む

ReLU 関数とその派生

前回記事の続き。

white-azalea.hatenablog.jp

ReLU に関して深掘りして調べてみた。
ReLU は DeepNeuralNetwork に使われる…という知識はあったのだけど、調べてみると関連する活性関数が沢山あった。

ReLU

これは分かりやすい

import numpy as np


def relu_func(x):
    return np.where(x <= 0, 0, x)

Leaky ReLU

こちらもわかりやすい、というかこれも前回実装してる

alpha = 0.01

def leaky_relu_func(x):
    return np.where(x <= 0, alpha * x, x)

Parametric ReLU

Leaky ReLU のアルファ値が学習によって動的に変わる。


  \alpha \geq 0 \\
  f(\alpha, x) = \left\{
      \begin{array}{cc}
        \alpha x & x \leq 0 \\
        x      & x > 0
      \end{array}
    \right.

つってもこれは単純な関数でもないので、しれっとは書けないか…

def prelu_func(x, alpha = 1.0):
    return np.where(x <= 0, alpha * x, x)

ELU

ELU(Exponential Linear Unit)というらしい。
指数的 LU というだけあり、以下の様な仕様らしい


  f(x) = \left\{
      \begin{array}{cc}
        \alpha(e^x - 1) & x \leq 0 \\
        x      & x > 0
      \end{array}
    \right.
def elu_func(x, alpha = 1.0):
    return np.where(x <= 0, alpha * (np.exp(x) - 1), x)

SELU

Scaled Exponential Linear Unit というらしい。
2017 年の論文で出てきたかなり新しい奴だそうだ。


  f(x) = \lambda \left\{
      \begin{array}{cc}
        \alpha (e^x - 1) & x \leq 0 \\
        x                & x > 0
      \end{array}
    \right.

導関数の形状は


  f'(x) = \lambda \left\{
      \begin{array}{cc}
        \alpha e^x & x \leq 0 \\
        1          & x > 0
      \end{array}
    \right.
SCALE = 1.0507
ALPHA = 1.6732

def selu_func(x, scale=SCALE, alpha=ALPHA):
  return scale * np.where(x <= 0, alpha * (np.exp(x) - 1), x)

とここまで紹介した段階で、どんな特性があるのかグラフにしてみる。

import matplotlib as mpl
import matplotlib.pyplot as plt
%matplotlib inline

x = np.linspace(-5, 5)

plt.plot(x, relu_func(x), label='relu')
plt.plot(x, leaky_relu_func(x), label='leaky relu')
plt.plot(x, elu_func(x), label='elu')
plt.plot(x, selu_func(x), label='selu')
plt.legend()
plt.show()

f:id:white-azalea:20210219202223p:plain

在宅になってから大分お世話になってるもの

まさにただの日記。
在宅になってから買ったもので、重宝しているものを以下に列挙する。

マグカップウォーマー

買ったのはコレ。
加熱部分が平たい形状をしているので、底が平らなカップならそのまま利用可能。
窪んでる形状なら、そこにアルミホイルを固めてはめ込む位しないとあったまらないのは泣き所。

2020年の新しいコーヒーカップウォーマーとオフィスウォーマー、5つの温度設定を備えた電気飲料ウォーマー、ココアミルク用のコーヒーウォーマー、オフィス用の自動オン/オフ重力センサーウォーマー、キャンドルワックスカップ、コーヒー 、 水/牛乳/お茶/コーヒードリングなど飲み物(最大80°C)(黒)

マグカップウォーマーでこれを買った理由は 5 段階で加熱設定ができて最大 80 度とのこと。
計測と体感だが、設定 1 = 40 度で、40,50,60,70,80度だと思われ(細かい温度が書いてない)

正式な温度計ではないけど、設定 3 ではいくら加熱してもゆで卵にならなかった(卵黄の固まる温度が 65 度。体感でそれなりに熱い)→ 設定 4 で完全ゆで卵(白身の固まる温度が 70 度以降)だったため。

卵をマグカップに入れて熱湯かけて、設定 3 で 12分すると、ちょうど温泉卵ができた。

Teplo ティーポッド

お茶専用機体。抽出温度、抽出時間、茶葉を揺らしながら抽出するなどをシステムで設定できる。
公式茶葉(の設定)であれば、リラックスしたい時用、仕事用などの抽出設定があり、心拍数や気温も加味して自動抽出してくれる。

お茶のサブスクリプションもサービスとしてあり、「寝る前」「仕事用」などの設定ができるのは公式茶葉のみ。
サードパーティのお茶(ルピシアとか)は、抽出プリセット(この温度、この時間、抽出のやり方の固定セット)を作っておける。

teplotea.com

これで紅茶を出すと、時間経過で濃くなるとか、温度ミスって渋くなったとかがないので便利。
※ 例えば、お茶の渋み成分であるカテキンは、75 度位から出てくるので、60 度で甘みだけを出す…なんてことができる。

とはいえ、茶葉に対して好みの設定を見つけるのは試行錯誤が必要。お茶マニア向けにw

モバイルモニター

デュアルディスプレイには必須だよねって事で。
元々は勉強会用に持ち運ぶ用モニタとして運用してましたが、コロナで在宅になってからは仕事用のセカンダリモニタに…

ASUS MB16ACR モバイルモニター モバイルディスプレイ 薄さ8mm・軽量780g、USBで簡単接続 15.6インチ IPS フルHD ブルーライト軽減 USB Type-C

場所を取らずに取り回しが楽なのが良いところ。
簡単に片づけできるしね!

ノートパソコン用スタンド

PCを作業するにあたって、ディスプレイの高さを上げると

  • 傾斜ができてキーが打ちやすい
  • 視線がちょっと上がるので、姿勢が少しだけマシになる

長時間作業してると結構来る。

因みに自分の好みは、PC の背中に貼って持ち上げる形式。
何せ、本体と別に持ち歩かなくていいのがよい。

Mac ならこれが便利。

Newanna laptop stand ノートPC スタンド ノートパソコンスタンド タブレット ラップトップスタンド ホルダー 折りたたみ インビジブル 軽量 携帯型 コンパクト 超薄 放熱対策 滑り止め付き MacBook Pro/iPad Pro/Surface Laptop/ASUS/Acer/Brother/DELL/東芝(TOSHIBA)/富士通対応(グレー)

因みに、持ち運びケースも持ってて、突っかかるのが嫌な場合はこっち

MOFT パソコンスタンド pcスタンド 目立たない 超薄型 ラップトップスタンド 粘着タイプ 繰り返し利用可能 完璧な角度調整可能 15.6インチのPCまで対応

両方持ってるが、前者でも 5-6mm 位の厚さでしかないので、ケースによってはそのまま入る。
ただし傾斜はそこまでないので、もっと傾斜が欲しければ 2 段階で傾斜を選べる MOFT がおすすめ。

背面に通気口がある Windows 系ノートの場合は、

ONED Majextand 人間工学に基づく、世界最薄スタンド(カラー:スペースグレー) MJX200/GRY グレー

接着部分はフレームの上と下部分で、内側が開く仕様。
一応金属製なので、閉じていても熱伝導しないことはないので、Windows マシンで背面貼り付け型はコレ一択かな…。

ニューラルネットワーク周りの関数

具体的には活性関数と呼ばれる連中。

これは入力を受けて結果を応答する関数。
調べてみると結構いっぱいある。

ステップ関数

0 基準で 0 か 1 かという単純なもの。


    \boldsymbol{y} =
        \left\{
            \begin{array}{cc}
                0 & (x \leq 0) \\
                1 & (x > 0) \\
            \end{array}
        \right.

in python

import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
%matplotlib inline


def step_func(x):
    return np.where(x <= 0, 0, 1)


x = np.linspace(-5, 5)
y = step_func(x)

plt.plot(x, y)
plt.show()

f:id:white-azalea:20210217205027p:plain

シグモイド関数

もう一つの関数がシグモイド関数
まぁこっちの方が定義が単純


  y = \frac{1}{1 + e^{-x}}
def sigmoid(x):
    return 1 / (1 + np.exp(-x))

y = sigmoid(x)
plt.plot(x, y)
plt.show()

f:id:white-azalea:20210217205117p:plain

素敵なことに、シグモイド関数だと微分が楽。


  y' = (1-y)y

ハイパボリックタンジェント

シグモイドに近い特性がありますが、こいつは -1 から 1 までの値域を持ってる。


  y = \frac{e^x - e^{-x}}{e^x + e^{-x}}

Tex 書式で書きづらいw

def tanh(x):
    return np.tanh(x)


y = tanh(x)
plt.plot(x, y)
plt.show()

f:id:white-azalea:20210217205233p:plain

ReLU

ReLU 関数というと、0 から線形に伸びる関数


y = \left\{
      \begin{array}{cc}
        0 & (x \leq 0) \\
        x & (x > 0)
      \end{array}
    \right.
def relu(x):
    return np.where(x <= 0, 0, x)


y = relu(x)
plt.plot(x, y)
plt.show()

f:id:white-azalea:20210217205328p:plain

LeakyReLU

マイナスの際にちょっとだけマイナスに伸びてる ReLU 関数。
0 でボーダーしやすい。

def leakey_relu(x):
    return np.where(x <= 0, 0.01*x, x)


y = leakey_relu(x)
plt.plot(x, y)
plt.show()

f:id:white-azalea:20210217205410p:plain

ソフトマックス関数


y = \frac{e^x}{ \sum^{n}_{k=1} e^{x_k} }
def soft_max_function(x):
    return np.exp(x) / np.sum(np.exp(x))


y = soft_max_function(x)
plt.plot(x, y)
plt.show()

f:id:white-azalea:20210217205506p:plain

統計のメモ

正規分布

統計つっても正規分布に関するもの。
正規分布ガウス分布ともいわれてる。

bellcurve.jp

この辺が分かりやすいはず。

要するに、平均値を中心(かつ最大出現数)に対象に見えるデータ分布をガウス分布と呼んでる。

例えば平均点 65 点で、標準偏差 10 点のテストがあるとしたとき、データはこんな感じ。
200 行程作成してみた。

scores = [
    69, 90, 77, 52, 69, 64, 55, 58, 77, 70, 55, 69, 75, 74, 78, 52, 68, 76, 78, 96,
    74, 64, 77, 60, 68, 61, 79, 67, 63, 71, 66, 75, 84, 76, 66, 65, 61, 54, 58, 41,
    58, 65, 69, 75, 67, 74, 54, 60, 66, 64, 67, 82, 75, 70, 64, 80, 71, 71, 39, 85,
    79, 68, 54, 48, 75, 68, 51, 61, 58, 46, 66, 62, 85, 75, 53, 77, 53, 61, 58, 54,
    66, 70, 65, 71, 67, 58, 67, 97, 53, 39, 65, 45, 54, 72, 65, 79, 63, 32, 58, 77,
    70, 58, 68, 65, 55, 49, 63, 65, 73, 71, 59, 68, 77, 64, 55, 84, 56, 68, 71, 73,
    65, 68, 69, 64, 72, 57, 60, 46, 60, 74, 60, 55, 60, 79, 63, 52, 68, 55, 73, 71,
    46, 57, 76, 66, 93, 61, 85, 76, 65, 76, 74, 72, 85, 72, 63, 58, 77, 52, 64, 60,
    70, 65, 61, 79, 82, 55, 59, 61, 90, 56, 75, 70, 76, 55, 62, 60, 52, 60, 56, 55,
    48, 43, 75, 66, 54, 75, 62, 66, 66, 79, 43, 54, 68, 54, 60, 64, 74, 83, 64, 73
]

因みにこれは Excel で自動生成したデータで、=NORMINV(RAND(), 65, 10) とか打ち込んでやれば生成できる。
厳密には、CEILING.MATH で小数点以下も削ってるがご愛敬。

このままだと分かりづらいので、自分が分かりやすい pandas に型変換して

import pandas as pd
import numpy as np

score_se = pd.Series(pd.array(scores))
score_np = np.array(scores)
print(score_se)
0      69
1      90
2      77
3      52
4      69
       ..
195    64
196    74
197    83
198    64
199    73
Length: 200, dtype: Int64

まずは統計量出そうか

score_se.describe()
count    200.000000
mean      65.670000
std       10.984278
min       32.000000
25%       58.000000
50%       66.000000
75%       74.000000
max       97.000000
dtype: float64

これを matplotlibヒストグラムにしてみる。
なんとなく左右対称なのが見えるはず

import matplotlib as mpl
import matplotlib.pyplot as plt
%matplotlib inline

plt.xlabel('score')
plt.ylabel('count')
plt.hist(score_se, bins=10)
plt.show()

f:id:white-azalea:20210214183345p:plain

大分真面目に記述すると、

平均値

各データ足し合わせして、データ数で割るので


  \mu = \frac{ \sum^n_{k=1}x_k }{n}

Python で書くと

print(sum(scores)/len(scores))
print(score_se.mean())
print(np.average(score_np))
65.67
65.67
65.67

分散値

各データの平均値との差を2乗したものをデータ数で割る。
ひいては、どの程度平均値からバラつきがあるのかって話。


    \sigma^2 = \frac{ \sum^n_{k=1}(x_k - \mu)^2 }{n}

計算してみると、小数点以下に差が出てくるけど、計算上の丸め誤差だろうか?

print((sum([(v - 65.67) ** 2 for v in scores]))/len(scores))
print(score_se.var())
print(np.var(score_np))
120.65437185929649
120.05110000000005
120.0511

標準偏差

これは分散のルートを取るだけ。
平均的データは平均を中心にどの程度の距離に固まってるのかって話。


\sigma = \sqrt{ \frac{ \sum^n_{k=1}(x_k - \mu)^2 }{n} }
import math

print(math.sqrt((sum([(v - 65.67) ** 2 for v in scores]))/len(scores)))
print(score_se.std())
print(np.std(score_np))
10.984278395019697
10.956783287078377
10.956783287078375

おまけ

事前データを Excel で作ってたけど、Python でも生成可能

normal_vars = np.random.normal(65, 10, 10000)
plt.hist(normal_vars, bins=50)
plt.show()

f:id:white-azalea:20210214183755p:plain

という感じで。

ついでに、標準偏差の特性を改めて見てみると

print(np.std(normal_vars))
print(np.average(normal_vars))
10.063176440589054
64.73496920088009

と、平均値±標準偏差区間に存在するデータ数は

fmVar = 64.735 - 10.063
toVar = 64.735 + 10.063
len(list(filter( lambda x: fmVar <= x and x <= toVar, normal_vars )))
6823

= 68.23 % が平均値プラスマイナス 標準偏差 の内側にいると。

Wikipedia, 標準偏差 曰く、

f:id:white-azalea:20210214185207p:plain

ということで一致している。

微分のおさらい

つっても公式だけ。 証明することが重要なのではなくて、名前と概念を一致させることが最も重要と想定。

というのも、AI系の数学眺めて一番困るケースが

  • なんでそうなるの?→公式の知識不足
  • 説明の意味が分からない→単語の持ってる概念が分かってない

用語の説明を実に受けたくなりますねぇ

微分

これは基本的な部分か。とりあえず公式だけ列挙

微分の表し方。

 f(x)

に対して、導関数微分された関数)は以下左右どっちかの書き方をする。


f'(x) = \frac{d}{dx}f(x)

公式

基本式


f(x) = x^r

これを微分する場合、


\frac{d}{dx}f(x) = rx^{r-1}

となる。ついでを言うと、微分対象の x を含まない定数に微分をかけると、その項は消滅する。
複数関数の微分の場合は、各項に微分がそれぞれかかるとみなせる


\frac{d}{dx}(f(x) + g(x)) = \frac{d}{dx}f(x) + \frac{d}{dx}g(x)

これをサンプル的に試すと


\frac{d}{dx}(2x^3 + 4x + 8) = \frac{d}{dx}2x^3 + \frac{d}{dx}4x + \frac{d}{dx}8 \\
 = 6x^2 + 4
続きを読む