swig+crf++0.58+java環境配置詳解(win+linux)

前言


      因爲剛在公司接手了一個使用crf++做對象識別的項目,該項目之前一直不能在windows上運行(crf++需要配置相應的環境,並且如

果想和JAVA整合需要用swig來封裝動態鏈接庫形成JNI接口),而且也缺乏日誌,所以就想直接配置出windows的開發調試環境,在網

上搜索了很多前輩的方法,很受啓發,但是也有一些語焉不詳的地方讓我入了不少坑,所以在此準備將Linux的Crf+java整合方法和

windows的Crf+java環境配置方法都整理出來,也爲自己之後的留用,也爲給有同樣需求的同學提供一些小小的幫助。

配置步驟


    1.windows


        軟件環境  win10 + crf++0.58win32  + jdk1.7.0._45(win32) + swigwin3.0.10 + swig-3.0.12 + visual studio2017(crf和swig之類的

東西會在末尾打包留種的)

     Tip:關於爲什麼使用32位的jdk是因爲crf++0.58只有linux版本和win32版本的,如果用64位的jdk的話在加載libcrfpp.dll的時候容易出現Can't load IA

32-bit .dll on a AMD 64-bit platform的問題,當然不是說不能搞,只不過爲了方便起見,博主還是直接安裝了一個32位的jdk,關於win上安裝多個jdk有

時候會出現改環境變量不好使的情況,這個時候可以檢查下 控制面板-》java-》java-》查看 在裏面設置運行時環境設置,如果還不好使的話你

C:\Windows\System32\目錄下絕對有java.exe,javaw.exe,javaws.exe這些文件,直接刪掉就好,這個操作的詳細描述請戳



     由於CRF++是用c++編寫的條件隨機場工具,爲了在JAVA爲主體的程序中使用的話就應該使用JNI技術對java進行擴展,並將CRF++編譯爲可供java

調用的動態鏈接庫。SWIG可以幫我們將C++編寫的CRF++和JAVA系統進行聯合。

    首先將 XXX\CRF++-0.58\sdk(windows版) 目錄下的crfpp.h,libcrfpp.lib兩個文件拷貝出來放在一個單獨的文件夾裏,在將XXX\CRF++-0.58\swig

下的CRFPP.i和version.h拷貝出來放在同樣的目錄下,這個時候這個目錄的截圖是這樣的。

        打開CRFPP.i,在倒數第二行的地方將%include ../crfpp.h   改爲    %include crfpp.h  因爲他們現在都在同一個文件夾下了嘛。



      之後我們需要使用win版的swig了,直接解壓就可以用,你也可以將swig的swig.exe添加進環境變量,這樣不需要每次使用都再輸一大串的地址。

      如果配置了swig環境變量  swig –c++ -java -package org.anon.crfpp CRFPP.i   (-package 後面的包名自己隨便起的啦)

      沒配的話就給一個全路徑咯  /d/crf++Env/swig3.0.10win/swigwin-3.0.10/swig.exe -c++ -java -package com.anon.crfpp /d/crf++Env/sdkCol/CRFPP.i

(我是在git bash裏執行的,cmd的自己轉下路徑格式)


    然後在我們的文件夾中可以看到以下文件。


      *.java就是swig生成的調用文件,測試類可以去linux版的crf++0.58下的java目錄下拷貝出test.java類,將這些類拷進一個項目中。


 


    接下來就是最容易出錯也是最麻煩的環節了,我們要編譯一個dll動態鏈接庫,在這裏我使用的是Visual studio 2017,當然任何版本的都是可以的,



     在項目配置嚮導這裏記得要選擇dll,附件選項選上空項目即可,要不然會有一堆然並卵的東西生成。

     接下來我們將生成的CRFPP_wrap.cxx(和*.java一起生成的)文件拷貝入CRFPP項目中,放在源文件下


這個時候你可以試着右鍵項目,生成一下,會報錯誤如下


這是因爲我們編譯dll還需要JDK中jni.h的幫助,這個時候我們可以對項目進行少許配置。

右鍵工程點擊屬性  配置屬性-》VC++目錄中進行如下配置



     將包含目錄中添加你使用的jdk的include目錄( xxx\java\jdk_1.7.0_45win32\include) ,和include下的32win目錄(xxx\java\jdk_1.7.0_45win32

\include\win32)。

    在庫目錄下添加win版的crf++的sdk文件夾,也就是libcrfpp.lib的目錄(xxx\crf++Env\CRF++-0.58\sdk)。

    網上有的博客說這樣就可以生成成功了,大家可以試一下,反正我配置到這一步沒有生成成功,報之下的錯誤




   如果你到這一步能生成成功那很Nice,不能的話那就接着按之下的步驟進行配置。

   依舊是右鍵項目,屬性,鏈路器下的常規再配置下附加庫目錄,

   

  接着還沒完,在鏈路器下的輸入里加上libcrfpp.lib,編輯裏直接輸就可以



   OK,全部配置流程走完了。build一下試試。


    果不其然的生成成功了,但是請注意這個時候是Debug模式生成的dll,這個時候我們要再調到Release模式生成一遍dll,使用release的dll去進行

JAVA整合調用。對的,是不是又報錯了?那是因爲Release和debug的屬性是兩套,再練一遍熟下手吧,我也是爲你好大笑


    接下來就是和JAVA項目整合了,在項目裏建一個文件夾,我比較習慣取名lib,將剛生成的dll文件和win版的CRF++0.58目錄下的 libcrfpp.dll都拷入文

件夾下。



   然而工作並沒有結束,我們要在JRE System Library裏添加入lib的配置路徑,右鍵點擊JRE System Library 然後build Path ->configure build path

  

     將之前的lib文件夾目錄配置入Native library location中,如下所示

  

  然後運行test.java 的main方法,不過記得之前將他讀取的模型路徑改變一下

  如果沒有模型的話在附件裏找就行,友情提供一個。


   然後當你滿懷激動的心情運行的時候,他偏偏有可能報這個錯

 

       這是因爲我們的dll庫並不叫CRFPP,而是叫CRFPP_demo,我們load的library應該是和這個dll庫同名的,然後我們很無奈的改了loadLibrary的參數

以後,他很有可能還會報一個錯。


  

  
      這句話的意思是找不到依賴的dll包,感覺這個有很多種解決方案,有人說可以直接在C:\Windows\System32文件夾下加入libcrfpp.dll就好,但是我嘗

試的並沒有什麼效果,同樣嘗試了感覺沒什麼效果的可以再加一行load庫的代碼如下。然後運行成功




     這是在eclipse下的crfpp配置,IDEA下的其實也差不多,有人想配的話照着這個流程來就行,實在出不來了給我留言我更新下,windows佔的篇幅太

多了,有一些坑沒有全部列出來,如果有哪些坑以上沒有涉及到可以留言,我再更新(畢竟win下坑還是蠻多的)。



    2.Linux

       軟件環境  CentOS release 6.9 (Final),CRF++0.58,pcre-8.32.tar.gz,swig3.0.12, java version "1.8.0_111".

 

      首先確認一點,你的jdk如果是openjdk的話你需要刪除它,安裝正常的jdk,就是打印java -version出現信息是如下這樣的jdk


     java version "1.8.0_111"
    Java(TM) SE Runtime Environment (build 1.8.0_111-b14)
     Java HotSpot(TM) 64-Bit Server VM (build 25.111-b14, mixed mode)


    卸載方法自行百度,jdk安裝方法也不多說了,都很簡單。

  

  

           tar -zxvf CRF++-0.58.tar.gz  解壓

           然後cd進去三步走起

 

./configure

make

make install



    如果沒有安裝g++會報錯應該,安裝的命令是:yum install -y gcc-c++



   如果三步進行完了我們就可以開始訓練自己的模型了,正好也測試下crf++到底好不好使。



   在訓練模型的時候需要模板和語料,這個大家可以自己上網找一下,我在附加中也會提供一些簡單的僅供測試的語料和模板,關於模板和


模型之類的知識不是本文討論的重點,大家可以自行查閱相關文章。


訓練模型   crf_learn segment_template train.data test.model -t  (segment_template是模板,train.data是訓練語料,test.model


是生成的模型名字, -t的意思是生成可讀的模型,可用於深入理解CRF模型)


如果報以下錯誤


crf_learn: error while loading shared libraries: libcrfpp.so.0: cannot open shared object file: No such file or directory

 
則修改/etc/ld.so.conf文件,加入 include /usr/local/lib,執行/sbin/ldconfig -v,刷新LIB庫,再試試就好用了。

   




   然後用生成的模型來標註下測試語料,

      crf_test -m seg_1_test.model test.data > result.txt (-m 後面選擇要使用的模型,test.data是要標註的語料,result.txt是標註結

果,本文提供的測試語料是簡單的BMES標註,只爲熟悉流程。train.data和result.txt的內容應該是一樣的,你也可以找一些其他的測試語料來測

試模型的標註效果。PS:本文語料選擇中石化新聞網)。

   


    OK,測試CRF運行無誤以後我們開始用swig整合JNI接口聯合JAVA。

  
    tar -zxvf swig-3.0.12.tar.gz 使用命令解壓swig,然後cd進入swig目錄。

    將pcre-8.32.tar.gz拷貝入swig目錄,在目錄下依次執行

   

./Tools/pcre-build.sh

./configure

make

make install

     

    然後可以用swig -version查看版本

  


   顯示版本則證明swig安裝成功,這個時候我們開始使用swig將crf++封裝爲JNI接口。

   cd CRF++-0.58/swig/ 進入CRF下的swig目錄。
 
   make

  然後再進入crf下的java目錄  cd ../java/

   make

  這個時候報錯了,找不到jni.h

 

 

打開文件CRFPP_wrap.cxx,找到這一行 : #include <jni.h> ,將這一行改爲:


#include "jni.h"


然後,到java的安裝目錄下,將這兩個文件(jni.h,jni_md.h)拷貝到 /crf0.58/java目錄下。


然後make,編譯成功


這個時候一般來講運行java test是不會直接就成功的,我們還需要對test.java做一些修改。



這個時候就把這裏的model路徑換成之前我們生成的model路徑。wq保存退出再make


很多人會發現然而這並沒有什麼用,該報錯還是報錯,那麼依序執行以下命令


cp libCRFPP.so/lib

cp libCRFPP.so/lib64

cp libCRFPP.so/usr/lib

cp libCRFPP.so/usr/lib64

chmod 775 /usr/lib64/libCRFPP.so

然後執行下列命令:

cd /usr/local/lib

cp libcrfpp.so.0 /usr/lib64


最後不要忘了回到CRF++0.58的java目錄下。


再試下java test。再沒結果給我留言












 



  






   




    


























發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章