Post Bank

If you have an idea that you genuinely think is good, don't let some idiot talk you out of it.

人口減少社会をどう生きるか

年末年始の休みでAI×人口減少 これから日本で何が起こるのかを読んだ。

AI×人口減少 これから日本で何が起こるのか

AI×人口減少 これから日本で何が起こるのか

「AI」と「人口減少」がタイトルには並列に書かれているが、この本の主題は「人口減少」の方。AIの話題については、申し訳程度でしかも若干否定派な意見が目立った。大まかな話の流れとしては、まず日本の人口減少問題の現状と未来予想について実際の予測数値を見ながら語られる。次に人口減少の原因分析と人口減少が引き起こす問題点について論じる。そしてタイトルにあるAIと人口減少問題を絡めて、その課題について指摘する。最後に、人口減少問題に対する取り組み例や筆者の提案する解決策が紹介されて幕を閉じる。といった流れ。

筆者は人口減少の原因をいくつか挙げているが、その中でも人口減少を引き起こす最も大きな要因は、東京への人口の一極集中だと述べている。人口の一極集中が引き起こす生活コストの増大長時間労働長時間通勤育児環境の悪化などが出生率の低下を招いているという。
これらの要因で起こる人口減少は、高齢化に繋がり、医療費・介護費の増大によって、税金・社会保障費の増大へと繋がり、働く世代の負担が増える。そのため消費が低迷し、経済成長率の低下を招くという。

人口減少社会において、AIなどの破壊的イノベーションは人手不足を解消し、生産性を高めることが期待される一方で、過度にAI化を進めれば深刻な人余りが起きてしまうのではないかと筆者は主張する。実際にアメリカでは、GAFAに代表されるIT企業は莫大な利益を上げてはいるが、雇用の人数はかなり少なく、一部の層が利益を独占してしまって、経済格差がこれまでにないほど広がっているそうだ。

日本にとっては踏んだり蹴ったりな状況となっているわけだが、この本は絶望に終わるわけではない。人口減少に歯止めをかける取り組みとして、企業の定年後の再雇用制度や本社の地方移転、地方大学の改革、社会保障分野への積極的なAI活用などを例に挙げている。AIの話題はあんまり出てこないにも関わらず、若干強引にAIとは闘うものではなく、利用するものだと締める。

人口減少の要因分析の話は読んでいて非常に納得感があった。自分も東京に住む働く世代の一人だが、確かに毎日の生活は結構苦しい。都市部の家賃は高すぎるから、郊外に家を借りて長時間の通勤に耐えているし、郊外とはいっても結構家賃は高くて家計を圧迫してくるからあんまり贅沢もできない。なるべく税金が安く済むように節税の情報をかき集めている。こんなカツカツの状況では、全く子供が欲しいとは思えない。こんな感じのことを感じている人は結構いるんじゃないかと思う。東京は子供を作ることに二の足を踏む環境であることは間違いない。

提案された解決策については至極もっともだなとは思うが、「AI・ロボット税」については反対したい。仕事の効率化を抑え込めば、結局長時間労働につながってしまうだろうし、先進国の日本がテクノロジーに対して消極的って大丈夫なのと思う。 あと定年が伸びるとか、貰える年金の受給額が少なくなるとか自分たちの子供の世代が不幸になるような政治はやめて欲しい。(定年が伸びるのが不幸と感じるかは人それぞれだが。)普通自分たちの後の世代が幸せに暮らせるように社会を作っていくのが政治家の仕事だろうに。結構政治に対する批判も多い本だったので、政治家に対する不信感も少し芽生えてしまったのだった。

脳内プロトタイピングの衝撃【エンジニアと人生】

以前紹介したVoicyの「エンジニアと人生」が更新されました。今回のゲストはうめのん氏ではなく、嶋田さんという方でした。話を聞いた感じだと今はゲームアプリ開発者だけど、元々はデザイナーの方なのかな?

voicy.jp

今回の話も面白かった。特に驚いたのが、脳内プロトタイピングの話。嶋田さんは、プロトタイピングを脳内で行うことで超高速でアプリ設計の検証を行うそうだ。まぁ言っている事はなんとなくわかるが、そんなことが普通の人に出来るのか、と思い少しやってみた。やってみるとわかるが、どうも同じUIや画面遷移やらが頭の中で堂々巡りしてしまう。なかなか新しい選択肢が次々と浮かんではこないので、テンポよく試行錯誤ができない。嶋田さんも言っていたけど、これは絶対に訓練が必要。というかこれは、嶋田さん自体の、デザイナーとしていろんな優れたビジュアルをインプットしてきたであろう経験も一つの助けになっているような気がする。嶋田さんは今から10年後に取り入れられるであろう手法を自分で考えて先取りしてるとは言っていたものの、このプロトタイピング手法がメジャーになるには人類自体の進化が必要そう。

うめのんさんに引き続き、二人目のゲスト嶋田さんも「自己流」を持ったスペシャリストでした。その人それぞれの自己流を聞くのも楽しいけど、その自己流が醸成されてきた経緯とか背景まで聞いてみたいと思うこの頃でした。


嶋田さんの開発したアプリ「PPKP」はこちらから。

PPKP

PPKP

  • SHIMADA TOSHIHIRO
  • ゲーム
  • 無料

Voicyはこちらから。

うめのんさんゲスト回の感想はこちら。

john-kaz.hatenablog.com

吉岡里帆 x 後藤正文(ASIAN KUNG-FU GENERATION)

UR LIFESTYLE COLLEGEという吉岡里帆さんがやってるラジオで、アジカン後藤正文さんがゲストでした。

www.youtube.com

なんかこういう裏話的な、人生の振り返り的な話を聞くのが好きかもしれない。アジカンの音楽は元々好きだけど、後藤さんが歌に込めたメッセージを知るとさらに好きになる。

このラジオの6:30くらいからの話が特にいいなぁと思った。若い頃は自分に出来ないこと、足りないことが許せなくて苛立ってたけど、年をとってくると自分たちに出来ること、出来ないことがわかってきて、出来ることを組み合わせて何か面白いことやってみようよと思うようになってきたという。まだ私自身の心境としては出来ないことが許せなくて、色々手を出してしまっているような状況だけど、年とってきたら同じような心境にたどり着けるだろうか。エンジニアはそんな心境に達してしまったら終わりだろうか。

アジカンのニューアルバム「HOME TOWN」が発売してます。買いたいです。
下はアルバム「HOME TOWN」の一曲「UCLA」。

UCLA

UCLA

Whitenoiseの仕様変更

v4.0より前

DjangoプロジェクトををHerokuでデプロイする時に、Django girls tutorialに従ってやると、wsgi.pyファイルに以下のように書くと思う。

wsgi.py

import os

from django.core.wsgi import get_wsgi_application
from whitenoise.django import DjangoWhiteNoise

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project.settings')

application = get_wsgi_application()
application = DjangoWhiteNoise(application)

v4.0以降

これで今までは動作してたのだが、ある時急にローカル環境がおかしくなってパッケージを一通り入れ直したら、whitenoiseのバージョンが上がってて、仕様変更が入っていた。

内容はこちらwsgi.pyファイルに上のように書く必要がなくなって、settings.pyのmiddlewareに追記すれば良くなったらしい。まずwsgi.pyファイルはプロジェクト生成した時のままで良くなって、こんな感じ。

wsgi.py

import os

from django.core.wsgi import get_wsgi_application

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project.settings')

application = get_wsgi_application()

settings.pyはMIDDLEWAREwhitenoise.middleware.WhiteNoiseMiddlewareを加えるのと、STATICFILES_STORAGEwhitenoise.django.GzipManifestStaticFilesStorageからwhitenoise.storage.CompressedManifestStaticFilesStorageに変更する。

settings.py

STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'whitenoise.middleware.WhiteNoiseMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ここを見ると、whitenoiseSecurityMiddlewareのすぐ後ろに書いて、他のmiddlewareよりも前に書かなければいけないらしい。

いつからこうなった

 Voicyで堤修一さんのエンジニアと人生というタイトルのチャンネルを聞いてみた。ゲストは個人アプリ開発者のうめのん氏。うめのん氏のブログはこちら。堤さんのブログはこちら

voicy.jp

 お二人とも特定の会社には属さずに(堤さんはアメリカの会社に一応籍は置いているみたいだが)、フリーで活動されているアプリ開発エンジニアだ。会社に属して平凡な毎日を送っている私からすると、羨ましいような生き方をされているという印象を受けた。羨ましいというのは、会社に縛られずに気楽に生きていけていいな〜とかいうことではなくて、アプリ開発という仕事を心から楽しんでいると聞いてて思ったからだ。堤さんなんかは、カンファレンスとかで海外に行っても、仕事の優先順位がかなり高くて、自由時間があったとしても観光に行きたいとも思わないそうだ。自分の寿命があと3年しかないと仮定した場合に、人のために今自分にできることは何かと考えたときに、それはやっぱりエンジニアとしてソフトウェアで世の中を少しでも変えていくことでしょ、という思考からそうなるらしい。人格者すぎる。そして実際に素晴らしいOSSも公開してるからすごすぎる。尊敬しかないです。

 他に印象に残ったのは、うめのん氏が1日で3時間しか仕事をしないということ。短時間で時間を区切ってやることで集中力が増して、作業効率が良くなるそうだ。そういえば茂木先生もフロー状態に入るには時間を区切ってやるのがいいってTwitterで言っていたような気がする。うめのん氏のこの方法は村上春樹のマネだそうで、村上春樹も朝6時間だけ執筆して昼は走って、みたいなルーティンらしくて、それを自分でも試しにやってみたそう。ただうめのん氏は6時間だと長すぎてだれてしまう時間できてしまったので、3時間にしたらめちゃくちゃ集中できたから3時間にしたと言ってた。うめのん氏のこの人のいいところを取り入れて、自分流にアレンジするという能力。そしてそれを継続する力。私も見習いたい。やっぱり出来る人というのは、自分流というのを持っている。

 このチャンネル、エンジニアが聞いたら面白いと思う。他人の仕事の仕方とか考え方とか生き方を聞くのは面白い。自分のスキルを磨いてきて腕一本で食っていっているような凄腕エンジニアの話だから少し自分の卑小さが惨めになって若干凹んだりもするけど、それもある種の刺激になって良い。エンジニアの皆さんは聞いてみては?

うめのん氏のアプリはこちら。

TensorFlow LiteのPost-training quantization

TensorFlow Lite公式ページに従って、以下のコードでweightの量子化をしてみた。

import tensorflow as tf

converter = tf.lite.TocoConverter.from_saved_model(saved_model_dir)
converter.post_training_quantize = True
tflite_quantized_model = converter.convert()
open("quantized_model.tflite", "wb").write(tflite_quantized_model)

これを実行すると、weightはfloat32からuint8に変換されるが、計算自体はfloat32のまま浮動小数点数で行われるそうだ。だから、Interpreter#runの入力はfloat32のまま。Post-training quantizationをしたからといって、デモでQuantized modelへの入力をuint8にしているようには出来ない。Full quantization modelを作成するには、Quantization-aware trainingをしないといけないらしい。参考

Androidで非同期処理【Android、Java】

AsyncTaskを使って非同期処理

適当なメソッドからAsyncTaskを直接呼び出して、非同期処理を実行しています。これだとThis AsyncTask class should be static or leaks might occurというWarningが出てしまいました。

public class MainActivity extends AppCompatActivity {

    /* 非同期処理の呼び出し */
    public void asyncTaskSample() {
        new AsyncTask<Integer, Integer, Integer>() {
            @Override
            protected Integer doInBackground(Integer ...params) {
                System.out.println("Hello World!!");
                return 0;
            }
        }.execute(0);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        asyncTaskSample();
    }
}

このエラーの原因を他のサイトから引用します。

  • 非staticな内部クラスは暗黙に親オブジェクト(Activityオブジェクト)への参照を持っている。
  • AsyncTaskが内部的に利用しているスレッドが生きている限りこのオブジェクトがガベージコレクションの対象にならない。

うーん、よくわからない。

この記事にあるように、「非static内部クラスインスタンスが存在する = 外部クラスインスタンスが存在する」という状態のため、非static内部クラスは外部クラスを参照することができるようです。そして参照を持つオブジェクトはガベージコレクションの対象にならないため、非同期処理が終わってもメモリから解放されない。これがメモリリークの原因になってしまうようです。わかったようなわからないような…。

で、原因がわかったところで上のコードをどう直したらいいかと言うと、Warningの通りにAsyncTaskstaticなクラスにする、もしくは、別クラスにすればいいです。以下はstaticなクラスにした例。

public class MainActivity extends AppCompatActivity {

    /* 非同期処理の呼び出し */
    public void asyncTaskSample() {
        MyTask task = new MyTask();
        task.execute(0);
    }

    private static class MyTask extends AsyncTask<Integer, Integer, Integer> {
        @Override
        protected Integer doInBackground(Integer ...params) {
            System.out.println("Hello World!!");
            return 0;
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        asyncTaskSample();
    }
}

ただこれでもまだ問題があって、上のコードだとActivityオブジェクトの非staticな変数にアクセスできないです。上のコードでは実装してないけど、ViewとかをMyTaskからいじりたかったりします。そこらへんをどうやってActivityオブジェクトから非同期処理に渡すのが最適かいまいちわかりません。

この記事では、AsyncTaskImageViewを渡すのに、コンストラクタで渡しているのですが、AsyncTaskImageViewへの参照を持たないように、WeakReferenceというのを使っています。参考までに、コードを引用させてもらいます。

class BitmapWorkerTask extends AsyncTask<String, Void, Bitmap> {  
    private final WeakReference<ImageView> mImageViewReference;  
    int mWidth;  
    int mHeight;  
    String mFilePath;  
  
    public BitmapWorkerTask(ImageView imageView) {  
        mImageViewReference = new WeakReference<ImageView>(imageView);  
        mWidth = imageView.getWidth();  
        mHeight = imageView.getHeight();  
    }  
  
    // バックグラウンドで画像をデコード  
    @Override  
    protected Bitmap doInBackground(String... params) {  
        mFilePath = params[0];  
        return decodeSampledBitmapFromFile(mFilePath, mWidth, mHeight);  
    }  
  
    // ImageView に Bitmap をセット  
    @Override  
    protected void onPostExecute(Bitmap bitmap) {  
        if (mImageViewReference != null && bitmap != null) {  
            final ImageView imageView = mImageViewReference.get();  
            if (imageView != null) {  
                imageView.setImageBitmap(bitmap);  
            }  
        }  
    }  
}

まとめ

結局、方法はいろいろあってどれが最適か正直わかりません。ただ明らかに間違っているコードもネットには散見されるので、注意が必要だなと感じました。(そう言いつつも自分の書いたコードが間違ってるかも...)AsyncTask奥深すぎる...

参考