5

私は Stanford CoreNLP ライブラリーを試していて、メインの StanfordCoreNLP パイプライン オブジェクトが java.io.NotSerializableException をスローしてもシリアライズしたいと考えています。

全文: 実装を実行するたびに、パイプラインのアノテーターと分類子をメモリにロードするのに約 15 秒かかります。終了プロセスのメモリは約 600MB です (私の場合は簡単に保存できるほど小さいです)。このパイプラインを最初に作成した後に保存したいので、後でメモリに読み込むことができます。

ただし、NotSerializableException がスローされます。Serializable を実装する簡単なサブクラスを作成しようとしましたが、StanfordCoreNLP にはこのインターフェイスを実装しないアノテーターと分類子のプロパティがあり、それらすべてのサブクラスを作成することはできません。

Serializable を実装していないオブジェクトをシリアライズする Java ライブラリはありますか? プロパティを再帰し、同様のオブジェクトに対して同じことを行う必要があると思います。

私が試したシリアライゼーションコード:

static StanfordCoreNLP pipeline;
static String file = "/Users/ME/Desktop/pipeline.sav";
    static StanfordCoreNLP pipeline() {
    if (pipeline == null) {
        try {
            FileInputStream saveFile = new FileInputStream(file);
            ObjectInputStream read = new ObjectInputStream(saveFile);
            pipeline = (StanfordCoreNLP) read.readObject();
            System.out.println("Pipeline loaded from file.");
            read.close();
        } catch (FileNotFoundException e) {
            System.out.println("Cached pipeline not found. Creating new pipeline...");
            Properties props = new Properties();
            props.put("annotators", "tokenize, ssplit, pos, lemma, ner, parse, dcoref");
            pipeline = new StanfordCoreNLP(props);
            savePipeline(pipeline);
        } catch (IOException e) {
            System.err.println(e.getLocalizedMessage());
        } catch (Exception e) {
            System.err.println(e.getLocalizedMessage());
        }
    }
    return pipeline;
}

static void savePipeline(StanfordCoreNLP pipeline) {
    try {
        FileOutputStream saveFile = new FileOutputStream(file);
        ObjectOutputStream save = new ObjectOutputStream(saveFile);
        save.writeObject(pipeline);
        System.out.println("Pipeline saved to file.");
        save.close();
    } catch (FileNotFoundException e) {
        System.out.println("Pipeline file not found during save.");
    } catch (IOException e) {
        System.err.println(e.getLocalizedMessage());
    }
}
4

2 に答える 2

2

一般に、データ オブジェクトを表すスタンフォード NLP クラス (Tree、LexicalizedParser など) はシリアル化可能ですが、プロセッサを表すクラス (StanfordCoreNLP、LexicalizedParserQuery、CRFClassifier) はシリアル化できません。あなたが求めるものを達成するには、多くのクラスをシリアライズ可能にする必要がありますが、それはそうではなく、その影響に対処する必要があります。

しかし、あなたの根底にある考え方は間違っていると思います。この 15 秒間に StanfordCoreNLP がロードしているものは、主に標準の Java シリアライズ オブジェクトです。NER 分類子とパーサー文法は、標準のシリアル化された Java オブジェクトです。(主に歴史的な理由から、POS タガー用を含め、いくつかはこの形式ではなく、単なるバイナリ データです。) 実際には、標準の Java シリアライゼーションを使用して多くのオブジェクトをロードするのはそれほど高速ではありません。 Java シリアライゼーションの速度と、代替の速度を比較する方法についての Web 上の議論を見つけてください。現在のすべてのシリアライズされたオブジェクトを含む、さらに大きなシリアライズされたオブジェクトを新しく作成しても、それほど速くはなりません。(すべてを 1 つの連続的なデータ ストリームにまとめることで、わずかな利益が得られる可能性があります。

むしろ、この問題に対処するための鍵は、システムを一度だけロードするコストを支払い、多くの文を処理している間、システムをメモリに保持することであると私は提案します。

于 2012-09-06T05:25:19.123 に答える
1

シリアル化できない唯一の理由が、としてマークされていないことである場合はSerializable、デフォルト以外のシリアル化戦略を回避できる可能性があります。たとえば、JacksonまたはXStreamを試すことができます。

とはいえ、そもそもそうでない正当な理由がある場合Serializable、これらの戦略は興味深い方法で破られる可能性があります。徹底的にテストしてください!

于 2012-09-04T04:38:06.657 に答える