質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.76%

  • Python

    6915questions

    Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

  • JSON

    1067questions

    JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

  • TensorFlow

    608questions

execution_count:nullをなんとかしたい

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 245

 前提・実現したいこと

某参考書のコードで画像キャプショニング
STAIRcaptionの画像データのinfo(JSONファイル)をTFRecord形式に整形したいのですが
いざpyソースコードファイルをコマンドプロンプトで実行しようとすると Nameerrorが出てしまいます
pythonでnullは対応されてない?みたいです
pythonコード内にexecution_countという項目は入れてないので

execution_countが何なのか、どこから来たのか分からないです。

execution_count:nullをなんとかしたいです

 発生している問題・エラーメッセージ

(tensorflow) C:\Users\User>python create_datasets.py
Traceback (most recent call last):
  File "create_datasets.py", line 197, in <module>
    "execution_count": null,
NameError: name 'null' is not defined

 ソースコード

import os
import json
import numpy as np
from collections import namedtuple, Counter
import tensorflow as tf

tf.flags.DEFINE_string("train_img_dir", "data/img/train2014/", "Training image directory.")
tf.flags.DEFINE_string("val_img_dir", "data/img/val2014/", "Validation image directory.")
tf.flags.DEFINE_string("train_captions", "data/stair_captions_v1.1_train.json", "Training caption file.")
tf.flags.DEFINE_string("val_captions", "data/stair_captions_v1.1_val.json", "Validation caption file.")
tf.flags.DEFINE_string("out_dir", "data/tfrecords/", "Output TFRecords directiory.")
tf.flags.DEFINE_integer("min_word_count", 4, "The minimum number of occurrences of each word in th training set for includion in the vocab.")
tf.flags.DEFINE_string("word_list_file", "data/dictionary.txt", "Output word list file.")

FLAGS = tf.flags.FLAGS

START_WORD = '<S>'
END_WORD = '<E>'
UNKNOWN_WORD = '<UNW>'

NUM_TRAIN_FILE = 256
NUM_VAL_FILE = 4
NUM_TEST_FILE = 8


ImageMetadata = namedtuple("ImageMetadata",["img_id", "filename"])

#画像メタデータと辞書をもとに、指定されたファイル数に分割してバイナリ(TFRecord)を作成する
def _create_datasets(name, img_meta, captions, word_to_id, num_file):

    #画像メタデータをだいたい等しく分割
    img_chunk = np.array_split(img_meta, num_file)
    counter = 0
    for i in range(1, num_file + 1):
        output_file_name = "%s-%.3d.tfrecord" % (name, i)
        output_file_path = os.path.join(FLAGS.out_dir, output_file_name)
        target_chunk = img_chunk[counter]
        #対象画像群書ごとにWriterを定義
        with tf.python_io.TFRecordWriter(output_file_path) as writer:
            for img in target_chunk:
                img_id = img[0]
                filename = img[1]
                #画像ファイルをバイト列として読み込み
                with tf.gfile.FastGFile(filename, "rb") as f:
                    data = f.read()

                #キャプションのid化
                caption = captions[int(img_id)]
                caption_ids = []
                for w in caption:
                    if w in word_to_id:
                        caption_ids.append(word_to_id[w])
                    else:
                        caption_ids.append(word_to_id[UNKNOWN_WORD])

                #固定長部分
                context = tf.train.Features(feature={
                    "img_id": tf.train.Feature(int64_list=tf.train.Int64List(value=[int(img_id)])),
                    "data": tf.train.Feature(bytes_list=tf.train.BytesList(value=[data])),
                    })

                #可変長部分
                caption_feature = [tf.train.Feature(int64_list=tf.train.Int64List(value=[v])) for v in caption_ids]
                feature_lists = tf.train.FeatureLists(feature_list={
                    "caption":tf.train.FeatureList(feature=caption_feature)
                    })

                #TFRecordに書き込み
                sequence_example = tf.train.SequenceExample(context=context, feature_lists=feature_lists)
                writer.write(sequence_example.SerializeToString())

        counter += 1

#jsonファイルを読み込み画像のid, ファイル名, キャプションを取得する。
def _load_metadata(caption_filename, img_dir):

    #jsonファイルをロード
    with open(caption_filename, 'r') as f:
        meta_data = json.load(f)

    #画像idとファイル名を持つnamedtupleのリストを作成
    meta_list = [ImageMetadata(x['id'], os.path.join(img_dir, x['file_name'])) for x in meta_data['images']]

    #スペース区切りのcaptionを単語の配列に変換
    def _create_word_list(caption):
        tokenized_captions = [START_WORD]
        tokenized_captions.extend(caption.split())
        tokenized_captions.append(END_WORD)
        return tokenized_captions

    #{画像id => キャプションのリスト}の辞書を作成
    id_to_captions = {}
    for annotation in meta_data["annotations"]:
        img_id = annotation['image_id']
        caption = annotation['tokenized_caption']
        caption = _create_word_list(caption)
        #キャプションはいくつかあるため1つだけを採用
        id_to_captions[img_id] = caption

    print("Loaded caption metadata for %d images from %s" % (len(meta_list), caption_filename))

    return meta_list, id_to_captions


def _create_vocab(captions):

    counter = Counter()
    for c in captions:
        counter.update(c)

    print("total words:", len(counter))
    #出現回数が一定数のものだけ辞書に採用。出現回数降順でソート
    #word_countsは(単語, 出現回数)のリスト
    word_counts = [x for x in counter.items() if x[1] >= FLAGS.min_word_count]
    word_counts.sort(key=lambda x: x[1], reverse=True)
    print("Words in vocab:", len(word_counts))


    #辞書作成
    word_list = [x[0] for x in word_counts]
    #<S>と<E>のidを1,0で固定したいので、一度削除して先頭に追加する
    word_list.remove(START_WORD)
    word_list.remove(END_WORD)
    word_list.insert(0, START_WORD)
    word_list.insert(0, END_WORD)

    word_list.append(UNKNOWN_WORD)
    word_to_id = dict([(x, y) for (y, x) in enumerate(word_list)])
    id_to_word = dict([(x, y) for (x, y) in enumerate(word_list)])
    return word_to_id, id_to_word


def main(argv):

    #jsonファイルからメタデータの読み込み
    #(画像id, ファイルパス)のタプルの配列と{id=>キャプションのリスト}を取得
    train_meta, train_captions = _load_metadata(FLAGS.train_captions, FLAGS.train_img_dir)
    val_meta, val_captions = _load_metadata(FLAGS.val_captions, FLAGS.val_img_dir)

    #キャプションをマージ
    captions = {k:v for dic in [train_captions, val_captions] for k, v in dic.items()}

    #訓練データ,バリデーションデータ,テストデータに分割
    train_cutoff = int(0.85 * len(val_meta))
    val_cutoff = int(0.90 * len(val_meta))

    train_dataset = train_meta + val_meta[0:train_cutoff]
    val_dataset = val_meta[train_cutoff:val_cutoff]
    test_dataset = val_meta[val_cutoff:]


    #訓練データから辞書作成
    train_captions = []
    for meta in train_dataset:
        c = captions[meta.img_id]
        train_captions.append(c)

    word_to_id, id_to_word = _create_vocab(train_captions)


    #画像を読み込みメタデータと結合したバイナリを作成
    _create_datasets("train", train_dataset, captions, word_to_id, NUM_TRAIN_FILE)
    _create_datasets("val", val_dataset, captions, word_to_id, NUM_VAL_FILE)
    _create_datasets("test", test_dataset, captions, word_to_id, NUM_TEST_FILE)

    # 単語リスト出力
    with open(FLAGS.word_list_file, 'a') as f:
        for k, v in id_to_word.items():
            f.write(v)
            f.write('\n')


if __name__ == "__main__":
    tf.app.run()

 試したこと

pyファイル内で null=Noneや null=''を試しましたが意味なかったです

 補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+2

状況がよくわかりませんが、json文字列があり、それを自前のスクリプトで整形してTFRecord形式にするということですか?
jsonのパースは標準ライブラリの機能でできますから、それを利用されてはいかがでしょうか。

19.2. json — JSON エンコーダおよびデコーダ — Python 3.6.5 ドキュメント

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/04/15 19:18

    質問文を一部書き忘れてすみません。目的はおっしゃる通りですが、コマンドプロンプトでいざpyファイルを実行しようとすると どこから来たのか分からないexecution_countが出現しました どうにかしてコレの意味と出処が知りたいです。

    提案ありがとうございます。処理できなかった場合利用させていただきます

    キャンセル

  • 2018/04/15 19:23

    これは先に書いておくべきでしたが、create_datasets.pyの当該部分のプログラムと説明を質問文追記で記載してください。
    execution_countはプログラム中に書いたのでなければ、入力データに含まれているのではないですか? ですから入力データをどのように受け取って処理しているのか確認しないと何とも言えません

    キャンセル

  • 2018/04/15 19:34

    申し訳ないです。プログラム記載しました

    確認したところ入力データにexecution_countは含まれていません。

    キャンセル

  • 2018/04/15 19:36

    とりあえず<code>のようなボタンを押して、コードブロックを使ってください。

    キャンセル

  • 2018/04/15 19:39

    了解しました

    キャンセル

  • 2018/04/15 19:48

    えーっと、そのコードが175行なのに197行からエラーが来ているようです。掲載時の省略でコード行数が変わってしまったか、エラーメッセージのtracebackを省略して掲載したか、実際に走っているコードと掲載されたコードがまったく違うかのいずれかだと思うので、確認してみてください。いずれにせよこれでは原因究明できません

    キャンセル

  • 2018/04/15 22:35

    パスやinput outputをもう一度設定したところ、エラーがなくなりました!
    恐らくおっしゃる通りで実際に走っているコードと違っていたかもしれないです。
    今動いていて感激です ありがとうございます

    キャンセル

  • 2018/04/15 22:38

    何か違うものを実行していたのですかね。pycとかかな? 不可解ですが、何はともあれ解決されたようでよかったです

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.76%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Python

    6915questions

    Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

  • JSON

    1067questions

    JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

  • TensorFlow

    608questions