2013年12月10日星期二

Mr.Mira

1) 下载

git clone https://github.com/kho/mr-mira.git

2) 安装
2.1) autoreconf -ifv
错误: 提示autoconf版本出错需要2.65以上版本, 而当前autoconf为2.63.
方法: 修改configure.ac文件第一行, 将AC_PREREQ(2.65)改为AC_PREREQ(2.63)

2.2)./configure --with-boost=/..../boost_1_53_0
错误: 提示一个boost::program_options...的错误
方法: 重新安装boost: ./bootstrap.sh -prefix=/.../boost_1_53_0
                                ./bjam install

错误: checking for glog... configure: error: Package requirements (libglog >= 0.3) were not met:

No package 'libglog' found

Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.

Alternatively, you may set the environment variables glog_CFLAGS
and glog_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.
方法: 安装glog, 设置glog_CFLAGS和glog_LIBS环境变量
         export glog_CFLAGS=-I/../glog/include
         export glog_LIBS=/../glog/lib/libglog.a
2.3) make


3) 使用
由于没有make install, 所以在使用的时候需要做如下修改scripts/run-mira-qsub.bash:
SUBMIT=`which qsub-mr.bash`
MAPPER=`which kbest_mirav5`
REDUCER=`which mr_mira_reduce`
-->
SUBMIT=/.../mr-mira/scripts/qsub-mr.bash
MAPPER=/.../mr-mira/mira/kbest_mirav5

REDUCER=/.../mr-mira/mira/mr_mira_reduce

[ ! -e "$OUTPUT" ] || { log "$OUTPUT already exists"; exit 1; }
-->
#[ ! -e "$OUTPUT" ] || { log "$OUTPUT already exists"; exit 1; }
注释掉此行. 通常我更喜欢将stderr, stdout重定向输出放入到$OUTPUT目录下. 如果$OUTPUT已存在, 该行代码将出错; 如果$OUTPUT不存在, 又无法重定向stderr, stdout. 因此注释掉此行代码.


QSUB_OPTS=(-q wide -l pmem=4g,walltime=2:00:00)
-->
if [ "x$PMEM" = x ]; then
    PMEM=4g
fi

QSUB_OPTS=(-q wide -l pmem=$PMEM,walltime=2:00:00)

添加一个PMEM参数用来控制申请内存大小.

run-mira-qsub.bash将多个作业提交到集群上跑.
run-mira-serial.bash是在单机上只开一个进程跑, 暂不支持多线程跑..

关于input文件的格式, 每个句子格式如下:

source ref rest
其中source指 source
      ref 如果有多个, 用 ||| 隔开
      rest暂可以不提供
见http://aclweb.org/anthology//P/P13/P13-4034.pdf

2013年8月2日星期五

cdec 获取top-best translation

viterbi.cc

prob_t ViterbiESentence(const Hypergraph& hg, vector* result) {
  return Viterbi(hg, result);
}


viterbi.h
template
typename WeightFunction::Weight Viterbi(const Hypergraph& hg,
                   typename Traversal::Result* result,
                   const Traversal& traverse,
                   const WeightFunction& weight) {
  typedef typename Traversal::Result T;
  typedef typename WeightFunction::Weight WeightType;
  const int num_nodes = hg.nodes_.size();
  std::vector vit_result(num_nodes);
  std::vector vit_weight(num_nodes, WeightType());

  for (int i = 0; i < num_nodes; ++i) {
    const Hypergraph::Node& cur_node = hg.nodes_[i];
    WeightType* const cur_node_best_weight = &vit_weight[i];
    T*          const cur_node_best_result = &vit_result[i];

    const unsigned num_in_edges = cur_node.in_edges_.size();
    if (num_in_edges == 0) {
      *cur_node_best_weight = WeightType(1);
      continue;
    }
    HG::Edge const* edge_best=0;
    for (unsigned j = 0; j < num_in_edges; ++j) {
      const HG::Edge& edge = hg.edges_[cur_node.in_edges_[j]];
      WeightType score = weight(edge);
      for (unsigned k = 0; k < edge.tail_nodes_.size(); ++k)
        score *= vit_weight[edge.tail_nodes_[k]];
      if (!edge_best || *cur_node_best_weight < score) {
        *cur_node_best_weight = score;
        edge_best=&edge;
      }
    }
    assert(edge_best);
    HG::Edge const& edgeb=*edge_best;
    std::vector antsb(edgeb.tail_nodes_.size());
    for (unsigned k = 0; k < edgeb.tail_nodes_.size(); ++k)
      antsb[k] = &vit_result[edgeb.tail_nodes_[k]];
    traverse(edgeb, antsb, cur_node_best_result);
  }
  if (vit_result.empty())
    return WeightType(0);
  std::swap(*result, vit_result.back());
  return vit_weight.back();
}


其中traverse调用ESentenceTraversal() --> TRule::ESubstitute()

2013年7月28日星期日

Perl一些代码

1) 得到当前目录

use Cwd            qw( abs_path );
use File::Basename qw( dirname );

my $current_dir = dirname(abs_path($0));


2) 使用regex进行部分lowercase替换

$line =~ s/( [^\(\)]+\))/lc($1)/ge;

((S (NP (DT The)(NN luxury)(NN auto)(NN maker))(NP (JJ last)(NN year))(VP (VBD sold)(NP (CD 1,214)(NNS cars))(PP (IN in)(NP (DT the)(NNP U.S.))))))

替换为
((S (NP (DT the)(NN luxury)(NN auto)(NN maker))(NP (JJ last)(NN year))(VP (VBD sold)(NP (CD 1,214)(NNS cars))(PP (IN in)(NP (DT the)(NNP u.s.))))))

3) 使用regex提取字符数组
my @terms = ($line =~ /\([^\(\)]+\)/g);

((S (NP (DT The)(NN luxury)(NN auto)(NN maker))(NP (JJ last)(NN year))(VP (VBD sold)(NP (CD 1,214)(NNS cars))(PP (IN in)(NP (DT the)(NNP U.S.))))))
提取出(DT The)  (NN luxury)  (NN auto)  (NN maker)  (JJ last)  (NN year) ....  (NNP U.S.)

2013年7月19日星期五

使用maxent zhang le

1) 下载
git clone https://github.com/lzhang10/maxent.git

2) 安装
按照INSTALL说明, 依次安装
$ brew install gfortran  (需要先安装howbrew (ruby -e "$(curl -fsSL https://raw.github.com/mxcl/homebrew/go)"), 见http://mxcl.github.io/homebrew/)

$./configure

$make

$make install

3) 使用, 在eclipse中,


#include "maxent/maxentmodel.hpp"
MaxentModel *pModel = new MaxentModel();
pModel->begin_add_event();
.....
pModel->add_event(vecContext, p, 1);
.....
pModel->end_add_event();
pModel->train(100, "lbfgs"); // train the model with 30 iterations of L-BFGS method

编译时在link这一步会提示关于gfortran的错误
需要在Properties属性中添加linker libraries (-l): gfortan, 以及linker libraries path: /usr/local/Cellar/gfortran/4.8.1/gfortran/lib


2013年7月15日星期一

cdec中的cube pruning

cdec的cube pruning代码对应于apple_models.cc的CubePruningRescorer类.


在传统的cky解码过程中, 我们会为每一个chart定义一个heap, 如heap[i, j]用来存放所以souce side span为[i, j]的hypothese. 该heap的大小通常限置为某个常数(如200). 并且要求每个hypothesis的概率不能小于heap[i,j][0]的某个倍数(如0.05).
在cube pruning的时候, 通过设置pop_limit来限制最多生成多少个hypotheses. 
heap中各项的排列通常是按照score + heuristic_lm_score (即未计算在score中的前面几个单词的lm值)

在cdec的void KBestFast(const int vert_index, const bool is_goal) 方法中, 并没有为每个span[i, j]设置一个heap. 在cube pruning的时候, 设置pop_limit来限制最多生成多少个hypotheses. 虽然没有为每个span[i, j]设置一个heap,  cdec用candidate heap(没有大小限制)来保存:

      D_v.resize(state2node.size());
      int c = 0;
      for (State2Node::iterator i = state2node.begin(); i != state2node.end(); ++i){
          D_v[c++] = i->second;
          // cerr << "MERGED: " << *i->second << endl;
      }
      //cerr <<"Node id: "<< vert_index<< endl;
      //#ifdef MEASURE_CA
      // cerr << "countInProcess (pop/tot): node id: " << vert_index << " (" << count_in_process_pop << "/" << count_in_process_tot << ")"<      // cerr << "countAtEnd (pop/tot): node id: " << vert_index << " (" << count_at_end_pop << "/" << count_at_end_tot << ")"<      //#endif
      sort(D_v.begin(), D_v.end(), EstProbSorter());


cdec默认设置pop_limit为200, 为了增加搜索空间, 似乎只能放大pop_limit的值.

cdec是这样做cube pruning,

假设source side span为[i, j], 其source端看以表达为  a X1 b X2 c, ..., a X1 c,..., 各个source端对应的目标端翻译, 加起来共有m种, t1, t2, ..., tm; X1可能的hypotheses有n种, X11, ..., X1n; X2可能的hypotheses有k种, X21, ..., X2k.

1:  生成一个candidate list = {(0, 0, 0), (1, 0, 0), ..., (m, 0, 0)}. 第1/2/3维分别为上面三个变量的下标. 
2:  pop = 0;
3:  while (pop < pop_limit && candidate_list not empty) do
4:     对candidate list排序;
5:     从candidate_list中取出最大项(i, j, k);
6      生成新的hypothesis;
7      对(i, j, k)扩展, 往candidate_list中添加(i, j+1, k)和(i, j, k+1);
8      pop ++


X11, ..., X1n和X21, ..., X2k是按大小排序的. 不确定t1, t2, ..., tm是否也是按大小排序, 但这应该没有关系.

2013年6月21日星期五

Fixfor is already running

Firefox is already running, but is not responding. To open a new window, you must first close the existing Firefox process, or restart your system.
http://www.mattcutts.com/blog/how-to-fix-firefox-is-already-running-error/

1) 通过 “ps auxwww | grep firefox” 找到firefox进程号, 然后“kill [processnumber]”.

2) 如果以上还不能解决, Step 1. 找到firefox的profile文件, 通常是 ~/.mozilla/firefox/profiles.ini 该文件里面会说明Path, 比如Path=src6ip5x.default Step 2. 在Path的路径下, 删除lock files. 需要删除“lock”和“.parentlock” .

2013年6月18日星期二

cdec forced decoding

cdec支持forced decoding, 数据准备格式为:

<seg grammar="grammar/gra.0.gz" id="0"> <s> 今年 前 两 月 广东 高新 技术 产品 出口 37.6亿 美元 </s> ||| <s> export of high-tech products in guangdong in first two months this year 37.6亿 us dollars </s> </seg>

有时候一些可以可以手工根据翻译规则拼成的translation, 在forced decoding的时候并没有找到, 可以关闭language model feature试试, 可能是由于language model的原因, 使得提供的translation并不在hyper-graph中.
 

2013年5月28日星期二

cdec添加一个模块

往cdec中添加一个模块, 以svmlight, maxent等classifiers为例.

1) 新建文件夹classifier, 在classifier/中实现svmlight.h/cpp, maxent.h/cpp, classifier.h/cpp

2) 在classifier/中新建Makefile.am, 内容可参照:

noinst_LIBRARIES = libclassifiers.a

libclassifiers_a_SOURCES = \
  svmlight.cpp \
  maxent.cpp \
  classifier.cpp
 
AM_CPPFLAGS = -W -Wall

这样libclassifiers.a可以在其他地方调用

3) 在主文件夹, 修改Makefile.am
在SUBDIRS项中添加classifier文件夹

4) 在主文件夹, 修改configure.ac
在末尾添加
AC_CONFIG_FILES([classifier/Makefile])

5) 重新开始编译(autoconf, configure, make等)


注意: 得看情况决定是否要修改decoder/ mira-vlad/下的Makefile.am文件, 即添加../classifier/libclassifiers.a和-I../classifier项

2013年4月3日星期三

往cdec中添加一个新feature

可按下面步骤:
1) 在decoder/目录下新建ff_feature_name.h和ff_feature_name.cc文件.
    在ff_feature_name.h中定义继承于FeatureFunction的类, 如何有需要, 定义继承于FactoryBase的factory类. 可参考ff_klm.h, ff_basic.h等.

2) 注册新定义的feature
    在decoder/cdec_ff.cc中注册新feature
    #include "ff_feature_name.h"
    在void register_feature_functions()中添加:
    ff_registry.Register("NewFeatureName", new NewFeatureFactory()); //如果定义了factory类
    或者
    ff_registry.Register("NewFeatureName", new FFFactory); //如果没有定义factory类

3) 在decoder/Makefile.am 中添加新定义的类(文件) ff_feature_name.cc, 可参考ff_klm类的写法.

4) 重新编译..


添加一个新的feature, contextual free, 但是需要用state来保留些信息, 用于快速计算该feature值.
这个时候需要注意, apply_models.cc/IncorporateIntoPlusLMForest(...), 里面(*s2n)[item->state_]会根据state值,决定是否产生一个新的node,或者丢弃. 因此在这之前需要将state里面的内容关于新feature的部分给erase掉. 按以下:
1) 在ff_set.h/ModelSet类里添加
public: 
FFState GetRealFFState(const FFState& state) const;
在该方法的实现中根据原state状态, 返回一个新的real_state, real_state里将新feature部分的state给删除掉了
2) 在apply_models.cc/IncorporateInputPlusLMForest(...)里:
Candidate*& o_item = (*s2n)[item->state_];
修改为

FFState real_state = models.GetRealFFState(item->state_);
Candidate*& o_item = (*s2n)[real_state];


assert(o_item->state_ == item->state_);    // sanity check!
修改为

assert(models.GetRealFFState(o_item->state_) == models.GetRealFFState(item->state_));  //sanity check!

附: GetRealFFState()实现
void ModelSet::GetRealFFState(const FFState& state, FFState& real_state) const {
real_state.resize(state.size());
for (int i = 0; i < state.size(); i++) {
real_state[i] = state[i];
}

if (state.size() == 0)
return;
assert(state.size() == state_size_);

//erase the states for SRLReorderFeature
for (int i = 0; i < models_.size(); i++) {
if (models_[i]->name_ == string( "NewFeatureName" )) {
int start_pos = model_state_pos_[i];
int end_pos;
if (i == models_.size() - 1)
end_pos = state_size_;
else
end_pos = model_state_pos_[i + 1];
for (int j = start_pos; j < end_pos; j++)
real_state[j] = 0;
}
}
}

FFState ModelSet::GetRealFFState(const FFState& state) const {
FFState real_state;
GetRealFFState(state, real_state);
return real_state;
}




2013年3月29日星期五

cdec一些細節

1) 讀取cdec.ini文件
line484: decoder.cc
DecoderImpl::DecoderImpl() at decoder.cc:484
Decoder::Decoder() at decoder.cc:740
main() at cdec.cc:14

2) 讀取weight.init文件
line15:weights.cc
Weights::InitFromFile() at weights.cc
DecoderImpl::DecoderImpl() at decoder.cc:571

Decoder::Decoder() at decoder.cc:740
main() at cdec.cc:14

3) 讀取language model文件
line91: ff_factory.h:92
FactoryRegistry::Create() at ff_factory.h:92
make_ff() at decoder.cc:131
DecoderImpl::DecoderImpl() at decoder.cc:604
Decoder::Decoder() at decoder.cc:740
main() at cdec.cc:14

4) 添加glue grammar
line51: scfg_translator.cc
GlueGrammar::GlueGrammar() at scfg_translator.cc:51
SCFGTranslatorImpl::SCFGTranslatorImpl() at scfg_translator.cc:134
SCFGTranslator::SCFGTranslator() at scfg_translator.cc:345
DecoderImpl::DecoderImpl() at decoder.cc:667
Decoder::Decoder() at decoder.cc:740
main() at cdec.cc:14


5) 讀取grammar文件
line303: rule_lexer.ll
RuleLexer::ReadRules() at rule_lexer.ll:303
TextGrammar::ReadFromStream() at grammar.cc:123
TextGrammar::ReadFromFile() at grammar.cc:119
TextGrammar::TextGrammar() at grammar.cc:80
SCFGTranslator::ProcessMarkupHintsImpl() at scfg_translator.cc:363
Translator::ProcessMarkupHints() at translator.cc:21
DecoderImpl::Decoder() at decoder.cc:791
Decoder::Decoder() at decoder.cc:746
main() at cdec.cc:30

6) input sentence轉換為lattice structure
line58: lattice.cc
LatticeTools::ConvertTextOrPLF() at lattice.cc:58
SCFGTranslatorImpl::Translate() at scfg_translator.cc:186
SCFGTranslator::TranslateImpl() at scfg_translator.cc:354
Translator::Translate() at translator.cc:33
DecoderImpl::Decode() at decoder.cc:794
Decoder::Decode() at decoder.cc:746
main() at cdec.cc:30

7) 添加pass through grammar
line65: scfg_translator.cc
PassThroughGrammar::PassThroughGrammar() at scfg_translator.cc:65
SCFGTranslatorImpl::Translate() at scfg_translator.cc:190
SCFGTranslator::TranslateImpl() at scfg_translator.cc:354
Translator::Translate() at translator.cc:33
DecoderImpl::Decode() at decoder.cc:794
Decoder::Decode() at decoder.cc:746
main() at cdec.cc:30



取消cdec中phrase長度限制

cdec中有三個參數來表示phrase span的單詞最大個數.

1) 抽取規則時, phrase在training sentences中的最大長度. 該變量的定義在sa-extract/sa-compile.pl中, my $max_size = 15; 可以通過sa-extract/sa-compile.pl -p max-size=10來修改;

2) 還是抽取規則時, phrase在test sentences中的最大長度. 既對於test sentences中的某個phrase, 如果長度超過該值, 那麼不去從training sentences中找匹配規則. 該變量的值在sa-extract/extract.ini文件中設置 (作為rulefactory.HieroCachingRuleFactory()的一個參數):
max_initial_size=15,             # maximum span of a grammar rule in TEST DATA

可以修改為max_initial_size=max_size, 既1)提到的phrase在training sentences中的最大長度. 雖然在sa-extract/extract.ini中也設置了max_size的值, 但該值會被sa-extract/sa-compile.pl中的值覆蓋掉.

3) Decoding的時候, scfg的長度, 在配置文件cdec.ini中設置. 如scfg_max_span_limit=12

往cdec取消phrase span單詞數的限制, 那麼需要修改以上三個參數, 比如:

1) 調用sa-compile.pl時, 設置-p, sa-extract/sa-compile.pl -p max-size=100000
2) 修改sa-extract/extract.ini, 將max_initial_size=15改為max_initial_size=max_size
    或者
    在調用sa-compile.pl生成的extract.ini文件中, 將max_initial_size=15改為max_initial_size=max_size
    (注: sa-extract/extract.ini是一個extract.ini的模板文件, sa-compile.pl輸出的extract.ini文件是以該文件為模板)
3)修改cdec.ini文件, 將scfg_max_span_limit=12改為scfg_max_span_limit=100000

2013年3月4日星期一

使用zpar的分词功能

1) 下载zpar http://faculty.sutd.edu.sg/~yue_zhang/doc/index.html
2) 阅读Chinese word segmentation文档http://faculty.sutd.edu.sg/~yue_zhang/doc/doc/segmenter.html 写得很清楚, zan
3) 编译make segmentor (将生成dict/segmentor/***)
4) 训练
     ./dist/segmentor/train <train-file> <model-file> <number of iterations>
     ./dist/segmentor/train ctb6.0/ctb6.0.train.segmented.txt ctb6.0/ctb6.0.seg.model 1
    (最后一个参数是迭代次数, 可以使用test.sh多次迭代然后选择最优值, 见Chinese word segmentation文档6 How to tune the performance of a system)
    (下载evaluate.py http://faculty.sutd.edu.sg/~yue_zhang/doc/doc/seg_files/evaluate.py)
    (需要修改test.sh里的一些文件名称路径等, 每次迭代会在原先迭代的基础上完成, 即为什么test.sh中总是执行$segmentor/train train.txt model 1)

#####test.sh#####
segmentor=dist/segmentor

rm model

for i in `seq 1 30`;
do
echo "iteration $i"
$segmentor/train ctb6.0/ctb6.0.train.segmented.txt model 1
$segmentor/segmentor model ctb6.0/ctb6.0.deve.unseg.txt ctb6.0.deve.autoseg.txt
python evaluate.py ctb6.0.deve.autoseg.txt ctb6.0/ctb6.0.deve.segmented.txt
cp model ctb6.0/ctb6.0.seg.model.$i
done
迭代18次的log:

239 iteration 18
240
241 Training started ...
242 Loading model ... done (8.39196s).
243 Computing averaged feature scores ... done
244 Saving model ... done.
245 Done.
246 Training has finished successfully. Total time taken is: 49.2729
247 Segmenting started
248 Loading model ... done (8.06785s).
249 Segmenting has finished successfully. Total time taken is: 11.2431
250 Word precision: 0.955604476243
251 Word recall: 0.955700108415
252 Word F-measure: 0.955652289936




5) 测试
    ./dist/segmentor/segmentor ctb6.0/ctb6.0.seg.model.18 ctb6.0/ctb6.0.test.unseg.txt ctb6.0.test.autoseg.txt

python evaluate.py ctb6.0.test.autoseg.txt ctb6.0/ctb6.0.test.segmented.txt

Word precision: 0.951947892344
Word recall: 0.949520704111
Word F-measure: 0.950732749098



   
 

使用stanford segmenter

1) 下载 http://nlp.stanford.edu/software/segmenter.shtml 当前最新版本为
1.6.72012-11-11. 大小为200M+, 其中的中文训练数据ctb.gz和pku.gz占了大概200M. 
将jar -xf stanford-segmenter-1.6.7-sources.jar 解压的文件夹放入src文件夹中.
用ant编译, 得到classes/文件夹

(jar xf stanford-segmenter-1.6.7-sources.jar
 mkdir src
 mv edu src/edu
 ant
 jar cvf seg.jar -C classes/ .)
这样生成新的seg.jar文件


2) 训练
  从ctb6.0中抽取了数据(train/test/deve按xue cl 08划分, train/test/deve:23420/2796/2079句)
  ctb_v6/data/utf8/bracketed/chtb_3095.fid的第89行((WHNP-4改为(CP (WHNP-4, 同时将第91行最前面的CP去除, 该句子为((IP (NP (CP (CP (IP (NP (NN 地方)(NN 当局))(VP (ADVP (AD 正在))(VP (VV 组织))))(DEC 的)))(ADJP (JJ 紧急))(NP (NN 求援)))(PU ,)(ADVP (AD 但是))(PP (P 据)(NP (NN 报道)))(PU ,)(NP (CP (CP (IP (VP (QP (CD 1多))(VP (VA 深))))(DEC 的)))(NP (NN 大雪)))(VP (PP (P 给)(NP (NN 求援)(NN 工作)))(VP (VV 造成)(AS 了)(NP (CP (CP (IP (VP (ADVP (AD 极))(VP (VA 大))))(DEC 的)))(NP (NN 困难)))))(PU 。)))

下载http://nlp.stanford.edu/software/trainSegmenter-20080521.tar.gz
大小为100M, 其中包括了中文ctb6.0的数据.
1) 准备 ctb6.train, ctb6.dev, and ctb6.test (需要按照ctb6.0的格式来准备, 会用到postagged信息)
2) 修改Makefile里面的
CTB6=/path/to/ctb6.0/
SEGMENTER=/path/to/stanford-chinese-segmenter-2012-11-11/
修改time java6 --> time java
3) make all
如果在第三步出错 可查看logs/ctb6.err
在8g内存机器上, 大概需要1个小时.

在Makefile里发现在训练的时候需要用到-serDictionary $(SEGMENTER)/data/dict-chris6.ser.gz
不知道dict-chris6.ser.gz内容是什么, 但应该不是从我提供的训练集中得到的...
(如果忽略这个东西, 把训练生成的mode/ctb6.ser.gz移到stanford-segmenter-2012-11-11/data/下, 去 替换ctb6.gz(还未试过))

2013年2月17日星期日

citibank网上银行往国内转账


1) citibank支持网上转账, 手续费是30$每笔(网上转要比到柜台转便宜些)

2) 选择网上转账及相关验证后, 需要填写/选择的项包括:
    a. Foreign Currency or US Dollars, 选择US Dollars, 即以美元的行式转到国内账号, 这可能要求国内账号有存储外币功能(听同事说到中国银行申请外币存储时需要预存大概100刀的样子). 不知道是不是选择US Dollars再到国内转成人民币要比直接选择Foreign Currency要划算一点?
    b. Select destination country: 选China
    c. enter bank's swift/bic: 这个可以问国内银行提供, 中国银行的也可以参考http://www.bankba.net/swiftcode/bc.htm, 这里我选择的是苏州分行(SUZHOU BRANCH) BKCHCNBJ95B

3) 下一个页面
      Beneficiary Name: 接收人姓名, 拼音就好, 但要确定名字拼音之间是否有空格 (比如: LI XIAO MING, LI XIAOMING). 这个应该看卡上都有
      Amount: 转出金额
     When: 可以选择单次转,还是按周期转(比如每周转一次等)

4) 下一个页面
     两部分信息, 一是关于接收人的信息:
    输入接收人的姓名/电话/地址/账号 (地址栏我空着, 没提供)
    Special instructions: 应该类似于附言, 填写吴江市分行的名称和地址(应该不填也没关系)
    另一信息是银行的信息:
    由于在前面输入了接收银行的swift code, 这个页面会自动填上银行的信息(比如苏州中国银行). 虽然转入的银行是吴江市分行, 但应该没问题, 都是苏州, 不去改动.
    CHIPS/UID#, 不太知道是什么, 但好像是跟银行与地址对应起来的代码, 类似邮政编码的功能?? 没有填写
    Intermediary Bank: 这里没有填写, 因为是直接转到中国银行, 应该不需要再来一个中转行. (是不是说如果转到国内一个小银行或地方性银行, 需要中转行??)

5) 下一个页面
    确定下就好..

6) 补充
    30$手续费是另付, 不是从汇出金额中扣. 大概两天就到国内账号上. 银行不会通知, 即不需要收件人确定. 中国银行会扣除12$作为手续费.