├── README.md ├── data └── rt-polaritydata │ ├── rt-polarity.neg │ └── rt-polarity.pos ├── data_helpers.py ├── model.py ├── test.py ├── train.py └── wor2vec └── wor2vec_model /README.md: -------------------------------------------------------------------------------- 1 | # cnn-text-classification 2 | cnn+word2vec做文本分类 3 | -------------------------------------------------------------------------------- /data_helpers.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import re 3 | import itertools 4 | from collections import Counter 5 | import cPickle 6 | import os 7 | 8 | def clean_str(string): 9 | """ 10 | Tokenization/string cleaning for all datasets except for SST. 11 | Original taken from https://github.com/yoonkim/CNN_sentence/blob/master/process_data.py 12 | """ 13 | string = re.sub(r"[^A-Za-z0-9(),!?\'\`]", " ", string) 14 | string = re.sub(r"\'s", " \'s", string) 15 | string = re.sub(r"\'ve", " \'ve", string) 16 | string = re.sub(r"n\'t", " n\'t", string) 17 | string = re.sub(r"\'re", " \'re", string) 18 | string = re.sub(r"\'d", " \'d", string) 19 | string = re.sub(r"\'ll", " \'ll", string) 20 | string = re.sub(r",", " , ", string) 21 | string = re.sub(r"!", " ! ", string) 22 | string = re.sub(r"\(", " \( ", string) 23 | string = re.sub(r"\)", " \) ", string) 24 | string = re.sub(r"\?", " \? ", string) 25 | string = re.sub(r"\s{2,}", " ", string) 26 | return string.strip().lower() 27 | 28 | 29 | def load_data_and_labels(): 30 | """ 31 | Loads MR polarity data from files, splits the data into words and generates labels. 32 | Returns split sentences and labels. 33 | """ 34 | # Load data from files 35 | positive_examples = list(open("./data/rt-polaritydata/rt-polarity.pos", "r").readlines()) 36 | positive_examples = [s.strip() for s in positive_examples] 37 | negative_examples = list(open("./data/rt-polaritydata/rt-polarity.neg", "r").readlines()) 38 | negative_examples = [s.strip() for s in negative_examples] 39 | # Split by words 40 | x_text = positive_examples + negative_examples 41 | x_text = [clean_str(sent) for sent in x_text] 42 | # Generate labels 43 | positive_labels = [[0, 1] for _ in positive_examples] 44 | negative_labels = [[1, 0] for _ in negative_examples] 45 | y = np.concatenate([positive_labels, negative_labels], 0) 46 | return [x_text, y] 47 | 48 | 49 | def load_vocab(sentences): 50 | vocab=[] 51 | for sentence in sentences: 52 | vocab.extend(sentence.split()) 53 | vocab=set(vocab) 54 | return vocab 55 | 56 | def load_bin_vec(fname, vocab): 57 | """ 58 | Loads 300x1 word vecs from Google (Mikolov) word2vec 59 | """ 60 | word_vecs = {} 61 | with open(fname, "rb") as f: 62 | header = f.readline() 63 | vocab_size, layer1_size = map(int, header.split()) 64 | print vocab_size,layer1_size 65 | binary_len = np.dtype('float32').itemsize * layer1_size 66 | for line in xrange(vocab_size): 67 | word = [] 68 | while True: 69 | ch = f.read(1) 70 | if ch == ' ': 71 | word = ''.join(word) 72 | break 73 | if ch != '\n': 74 | word.append(ch) 75 | if word in vocab: 76 | word_vecs[word] = np.fromstring(f.read(binary_len), dtype='float32') 77 | else: 78 | f.read(binary_len) 79 | return word_vecs 80 | 81 | 82 | 83 | def get_W(word_vecs, k=300): 84 | """ 85 | Get word matrix. W[i] is the vector for word indexed by i 86 | """ 87 | vocab_size = len(word_vecs) 88 | word_idx_map = dict() 89 | W = np.zeros(shape=(vocab_size + 1, k), dtype='float32') 90 | W[0] = np.zeros(k, dtype='float32') 91 | i = 1 92 | for word in word_vecs: 93 | W[i] = word_vecs[word] 94 | word_idx_map[word] = i 95 | i += 1 96 | return W, word_idx_map 97 | 98 | def add_unknown_words(word_vecs, vocab, k=300): 99 | """ 100 | For words that occur in at least min_df documents, create a separate word vector. 101 | 0.25 is chosen so the unknown vectors have (approximately) same variance as pre-trained ones 102 | """ 103 | for word in vocab: 104 | if word not in word_vecs: 105 | word_vecs[word] = np.random.uniform(-0.25, 0.25, k) 106 | return word_vecs 107 | 108 | 109 | 110 | 111 | def batch_iter(data, batch_size, num_epochs, shuffle=True): 112 | """ 113 | Generates a batch iterator for a dataset. 114 | """ 115 | data = np.array(data) 116 | data_size = len(data) 117 | num_batches_per_epoch = int(len(data)/batch_size) + 1 118 | for epoch in range(num_epochs): 119 | # Shuffle the data at each epoch 120 | if shuffle: 121 | shuffle_indices = np.random.permutation(np.arange(data_size)) 122 | shuffled_data = data[shuffle_indices] 123 | # shuffled_data=np.random.permutation(data) 124 | else: 125 | shuffled_data = data 126 | for batch_num in range(num_batches_per_epoch): 127 | start_index = batch_num * batch_size 128 | end_index = min((batch_num + 1) * batch_size, data_size) 129 | yield shuffled_data[start_index:end_index] 130 | 131 | def load_train_dev_data(): 132 | print("Loading data...") 133 | x_text, y = load_data_and_labels() 134 | 135 | # Randomly shuffle data 136 | np.random.seed(10) 137 | shuffle_indices = np.random.permutation(np.arange(len(y))) 138 | x_text = np.array(x_text) 139 | x_text = x_text[shuffle_indices] 140 | y_shuffled = y[shuffle_indices] 141 | 142 | max_sentence_length = max([len(x.split()) for x in x_text]) 143 | 144 | # Load set word 145 | word_set = load_vocab(x_text) 146 | 147 | # Load word2vec 148 | if os.path.exists("wor2vec/wor2vec_model"): 149 | wor2vec_model = cPickle.load(open("wor2vec/wor2vec_model", "rb")) 150 | else: 151 | wor2vec_model = load_bin_vec("GoogleNews-vectors-negative300.bin", word_set) 152 | wor2vec_model = add_unknown_words(wor2vec_model, word_set, 300) 153 | cPickle.dump(wor2vec_model, open("wor2vec_model", "wb")) 154 | 155 | x = [] 156 | for ste in x_text: 157 | words = ste.split() 158 | l = len(words) 159 | 160 | sentence = [] 161 | for i, word in enumerate(words): 162 | sentence.append(wor2vec_model[word]) 163 | 164 | zeros_list = [0] * 300 165 | 166 | for j in range(max_sentence_length - i - 1): 167 | sentence.append(zeros_list) 168 | 169 | x.append(sentence) 170 | 171 | x = np.array(x) 172 | 173 | # Split train/test set 174 | # TODO: This is very crude, should use cross-validation 175 | x_train, x_dev = x[:-1000], x[-1000:] 176 | y_train, y_dev = y_shuffled[:-1000], y_shuffled[-1000:] 177 | print("Train/Dev split: {:d}/{:d}".format(len(y_train), len(y_dev))) 178 | return x_train,y_train,x_dev,y_dev 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | -------------------------------------------------------------------------------- /model.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import tensorflow as tf 3 | import tensorlayer as tl 4 | import numpy as np 5 | class Model(object): 6 | """ 7 | A CNN for text classification. 8 | Uses an embedding layer, followed by a convolutional, max-pooling and softmax layer. 9 | """ 10 | def __init__( 11 | self, sequence_length, num_classes, 12 | embedding_size, filter_sizes, num_filters, dropout_keep_prob,l2_reg_lambda=0.0,hidden_unit=64): 13 | """ 14 | sequence_length – The length of our sentences. Remember that we padded all our sentences to have the same length (59 for our data set). 15 | num_classes – Number of classes in the output layer, two in our case (positive and negative). 16 | vocab_size – The size of our vocabulary. This is needed to define the size of our embedding layer, which will have shape [vocabulary_size, embedding_size]. 17 | embedding_size – The dimensionality of our embeddings. 18 | filter_sizes – The number of words we want our convolutional filters to cover. We will have num_filters for each size specified here. For example, [3, 4, 5] means that we will have filters that slide over 3, 4 and 5 words respectively, for a total of 3 * num_filters filters. 19 | num_filters – The number of filters per filter size (see above). 20 | dropout_keep_prob – The keep_prob of DropoutLayer 21 | """ 22 | self.input_x=tf.placeholder(tf.float32,[None,sequence_length,embedding_size],name="input_x") 23 | self.input_y=tf.placeholder(tf.float32,[None,num_classes],name="input_y") 24 | # self.dropout_keep_prob=tf.placeholder(tf.float32,name="dropout_keep_prob") 25 | self.dropout_keep_prob=dropout_keep_prob 26 | self.pad=tf.placeholder(tf.float32,[None,1,embedding_size,1],name="pad") 27 | # Keeping track of l2 regularization loss (optional) 28 | l2_loss=tf.constant(0.0) 29 | 30 | 31 | network=tl.layers.InputLayer(inputs=self.input_x, 32 | name="input") 33 | 34 | self.padnetwork=tl.layers.InputLayer(inputs=self.pad, 35 | name='padlayer') 36 | #Inserts a dimension of 1 into a tensor's shape 37 | network.outputs=tf.expand_dims(network.outputs,-1) 38 | 39 | 40 | # Create a convolution + maxpool layer for each filter size 41 | pooled_outputs_network = [] 42 | sl=[] 43 | for i,filter_size in enumerate(filter_sizes): 44 | with tf.name_scope("conv-maxpool-%s" % filter_size): 45 | 46 | sl.append(sequence_length-filter_size+1) 47 | networks=[network] 48 | networks.extend([self.padnetwork]*(filter_size-1)) 49 | filternetwork=tl.layers.ConcatLayer(layer=networks,concat_dim=1,name="pad-%s" % filter_size) 50 | 51 | #Convolution Layer 52 | convnetwork=tl.layers.Conv2dLayer(layer=filternetwork, 53 | act=tf.nn.relu, 54 | shape=[filter_size,embedding_size,1,num_filters], 55 | strides=[1,1,1,1], 56 | padding="VALID", 57 | W_init=tf.truncated_normal_initializer(stddev=0.1), 58 | b_init=tf.constant_initializer(0.1), 59 | name="conv-%s" % filter_size) 60 | #Maxpooling over the outputs 61 | poolnetwork=tl.layers.PoolLayer(layer=convnetwork, 62 | ksize=[1,1,1,1], 63 | strides=[1,1,1,1], 64 | padding="VALID", 65 | pool=tf.nn.max_pool, 66 | name="pool-%s" % filter_size 67 | ) 68 | poolnetwork2=tl.layers.ReshapeLayer(poolnetwork,shape=[-1,sequence_length,num_filters],name="poolreshape-%s" % filter_size) 69 | pooled_outputs_network.append(poolnetwork2) 70 | 71 | # Combine all the pooled features 72 | self.h_pool_network=tl.layers.ConcatLayer(layer=pooled_outputs_network,concat_dim=2) 73 | 74 | 75 | 76 | self.grunetwork=tl.layers.RNNLayer( 77 | layer=self.h_pool_network, 78 | cell_fn=tf.nn.rnn_cell.GRUCell, 79 | cell_init_args={}, 80 | n_hidden=hidden_unit, 81 | return_last=True, 82 | return_seq_2d=True 83 | ) 84 | 85 | # Add dropout 86 | self.dropoutnetwork=tl.layers.DropoutLayer(layer=self.grunetwork,keep=self.dropout_keep_prob,name="dropout") 87 | # 88 | 89 | # Final (unnormalized) scores and predictions 90 | with tf.name_scope("output"): 91 | self.outputnetwork=tl.layers.DenseLayer(layer=self.dropoutnetwork, 92 | n_units=num_classes, 93 | act=tf.identity, 94 | b_init=tf.constant_initializer(0.1), 95 | name="scores" 96 | ) 97 | self.scores=self.outputnetwork.outputs 98 | self.predictions=tf.argmax(self.scores,1,name="predictions") 99 | 100 | 101 | l2_loss+=tf.nn.l2_loss(self.outputnetwork.all_params[-2]) 102 | l2_loss+=tf.nn.l2_loss(self.outputnetwork.all_params[-1]) 103 | # CalculateMean cross-entropy loss 104 | with tf.name_scope("loss"): 105 | losses=tf.nn.softmax_cross_entropy_with_logits(self.scores,self.input_y) 106 | self.loss=tf.reduce_mean(losses)+tf.minimum(l2_reg_lambda*l2_loss,3) 107 | 108 | # Accuracy 109 | with tf.name_scope("accuracy"): 110 | correct_predictions = tf.equal(self.predictions, tf.argmax(self.input_y, 1)) 111 | self.accuracy = tf.reduce_mean(tf.cast(correct_predictions, "float"), name="accuracy") 112 | 113 | 114 | -------------------------------------------------------------------------------- /test.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import tensorflow as tf 3 | import numpy as np 4 | import os 5 | import time 6 | import datetime 7 | import data_helpers 8 | import cPickle 9 | from model import Model 10 | import tensorlayer as tl 11 | # Parameters 12 | # ================================================== 13 | 14 | # Model Hyperparameters 15 | tf.flags.DEFINE_string("filter_sizes", "3,4,5", "Comma-separated filter sizes (default: '3,4,5')") 16 | tf.flags.DEFINE_integer("num_filters", 128, "Number of filters per filter size (default: 128)") 17 | tf.flags.DEFINE_float("dropout_keep_prob", 0.7, "Dropout keep probability (default: 0.5)") 18 | tf.flags.DEFINE_float("l2_reg_lambda", 0.1, "L2 regularizaion lambda (default: 0.0)") 19 | 20 | # Training parameters 21 | tf.flags.DEFINE_integer("batch_size", 64, "Batch Size (default: 64)") 22 | tf.flags.DEFINE_integer("num_epochs", 200, "Number of training epochs (default: 200)") 23 | tf.flags.DEFINE_integer("evaluate_every", 100, "Evaluate model on dev set after this many steps (default: 100)") 24 | tf.flags.DEFINE_integer("checkpoint_every", 100, "Save model after this many steps (default: 100)") 25 | # Misc Parameters 26 | tf.flags.DEFINE_boolean("allow_soft_placement", True, "Allow device soft device placement") 27 | tf.flags.DEFINE_boolean("log_device_placement", False, "Log placement of ops on devices") 28 | 29 | # Eval Parameters 30 | tf.flags.DEFINE_string("checkpoint_dir", "/home/liuxiaoyu/PycharmProjects/cnn-text-classification-tf-master/runs/1478434371/checkpoints", "Checkpoint directory from training run") 31 | tf.flags.DEFINE_boolean("eval_train", False, "Evaluate on all training data") 32 | 33 | 34 | 35 | FLAGS = tf.flags.FLAGS 36 | FLAGS._parse_flags() #Loading Parameters 37 | print("\nParameters:") 38 | for attr, value in sorted(FLAGS.__flags.items()): 39 | print("{}={}".format(attr.upper(), value)) 40 | print("") 41 | 42 | 43 | npzfile=np.load(open("data/testdata.npz","rb")) 44 | x_train=npzfile['arr_0'] 45 | y_train=npzfile['arr_1'] 46 | x_test=npzfile['arr_0'] 47 | y_test=npzfile['arr_1'] 48 | 49 | # Training 50 | # ================================================== 51 | 52 | cnn = Model( 53 | sequence_length=x_train.shape[1], 54 | num_classes=y_train.shape[1], 55 | embedding_size=300, 56 | filter_sizes=list(map(int, FLAGS.filter_sizes.split(","))), 57 | num_filters=FLAGS.num_filters, 58 | dropout_keep_prob=FLAGS.dropout_keep_prob, 59 | l2_reg_lambda=FLAGS.l2_reg_lambda) 60 | saver = tf.train.Saver() 61 | sess=tf.InteractiveSession() 62 | 63 | cpkl=tf.train.get_checkpoint_state(FLAGS.checkpoint_dir) 64 | print cpkl.model_checkpoint_path 65 | if cpkl and cpkl.model_checkpoint_path: 66 | saver.restore(sess,cpkl.model_checkpoint_path) 67 | 68 | dp_dict=tl.utils.dict_to_one(cnn.outputnetwork.all_drop) 69 | feed_dict={cnn.input_x:x_test,cnn.input_y:y_test} 70 | feed_dict.update(dp_dict) 71 | 72 | print sess.run(cnn.accuracy,feed_dict=feed_dict) 73 | 74 | 75 | -------------------------------------------------------------------------------- /train.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | 3 | import tensorflow as tf 4 | import numpy as np 5 | import os 6 | import time 7 | import datetime 8 | import data_helpers 9 | 10 | from model import Model 11 | from tensorflow.contrib import learn 12 | import tensorlayer as tl 13 | import cPickle 14 | # Parameters 15 | # ================================================== 16 | 17 | # Model Hyperparameters 18 | tf.flags.DEFINE_string("filter_sizes", "3,4,5", "Comma-separated filter sizes (default: '3,4,5')") 19 | tf.flags.DEFINE_integer("num_filters", 128, "Number of filters per filter size (default: 128)") 20 | tf.flags.DEFINE_float("dropout_keep_prob", 0.7, "Dropout keep probability (default: 0.5)") 21 | tf.flags.DEFINE_float("l2_reg_lambda", 0.1, "L2 regularizaion lambda (default: 0.0)") 22 | 23 | # Training parameters 24 | tf.flags.DEFINE_integer("batch_size", 64, "Batch Size (default: 64)") 25 | tf.flags.DEFINE_integer("num_epochs", 200, "Number of training epochs (default: 200)") 26 | tf.flags.DEFINE_integer("evaluate_every", 100, "Evaluate model on dev set after this many steps (default: 100)") 27 | tf.flags.DEFINE_integer("checkpoint_every", 100, "Save model after this many steps (default: 100)") 28 | # Misc Parameters 29 | tf.flags.DEFINE_boolean("allow_soft_placement", True, "Allow device soft device placement") 30 | tf.flags.DEFINE_boolean("log_device_placement", False, "Log placement of ops on devices") 31 | 32 | FLAGS = tf.flags.FLAGS 33 | FLAGS._parse_flags() 34 | print("\nParameters:") 35 | for attr, value in sorted(FLAGS.__flags.items()): 36 | print("{}={}".format(attr.upper(), value)) 37 | print("") 38 | 39 | # Loading data 40 | # ================================================== 41 | x_train,y_train,x_dev,y_dev=data_helpers.load_train_dev_data() 42 | # 43 | # np.savez(open("data/testdata.npz","wb"),x_train,y_train,x_dev,y_dev) 44 | # tl.files.save_npz([x_train,y_train,x_dev,y_dev]) 45 | # x_train,y_train,x_dev,y_dev=tl.files.load_npz(path="data/",name="testdata.npz") 46 | 47 | # Training 48 | # ================================================== 49 | 50 | with tf.Graph().as_default(): 51 | session_conf = tf.ConfigProto( 52 | allow_soft_placement=FLAGS.allow_soft_placement, 53 | log_device_placement=FLAGS.log_device_placement) 54 | sess = tf.Session(config=session_conf) 55 | with sess.as_default(): 56 | cnn = Model( 57 | sequence_length=x_train.shape[1], 58 | num_classes=y_train.shape[1], 59 | embedding_size=x_train.shape[2], 60 | filter_sizes=list(map(int, FLAGS.filter_sizes.split(","))), 61 | num_filters=FLAGS.num_filters, 62 | dropout_keep_prob=FLAGS.dropout_keep_prob, 63 | l2_reg_lambda=FLAGS.l2_reg_lambda, 64 | hidden_unit=64 65 | ) 66 | 67 | # Define Training procedure 68 | global_step = tf.Variable(0, name="global_step", trainable=False) 69 | optimizer = tf.train.AdamOptimizer(1e-3) 70 | grads_and_vars = optimizer.compute_gradients(cnn.loss) 71 | train_op = optimizer.apply_gradients(grads_and_vars, global_step=global_step,name='train_op') 72 | 73 | # Keep track of gradient values and sparsity (optional) 74 | grad_summaries = [] 75 | for g, v in grads_and_vars: 76 | if g is not None: 77 | grad_hist_summary = tf.histogram_summary("{}/grad/hist".format(v.name), g) 78 | sparsity_summary = tf.scalar_summary("{}/grad/sparsity".format(v.name), tf.nn.zero_fraction(g)) 79 | grad_summaries.append(grad_hist_summary) 80 | grad_summaries.append(sparsity_summary) 81 | grad_summaries_merged = tf.merge_summary(grad_summaries) 82 | 83 | # Output directory for models and summaries 84 | timestamp = str(int(time.time())) 85 | 86 | out_dir = os.path.abspath(os.path.join(os.path.curdir, "runs", timestamp)) 87 | # tl.files.save_any_to_npy(save_dict={"x_test":x_dev,"y_test":y_dev,"x_train":x_train,"y_train":y_train},name="testdata.npy") 88 | print("Writing to {}\n".format(out_dir)) 89 | 90 | # Summaries for loss and accuracy 91 | loss_summary = tf.scalar_summary("loss", cnn.loss) 92 | acc_summary = tf.scalar_summary("accuracy", cnn.accuracy) 93 | 94 | # Train Summaries 95 | train_summary_op = tf.merge_summary([loss_summary, acc_summary, grad_summaries_merged]) 96 | train_summary_dir = os.path.join(out_dir, "summaries", "train") 97 | train_summary_writer = tf.train.SummaryWriter(train_summary_dir, sess.graph) 98 | 99 | # Dev summaries 100 | dev_summary_op = tf.merge_summary([loss_summary, acc_summary]) 101 | dev_summary_dir = os.path.join(out_dir, "summaries", "dev") 102 | dev_summary_writer = tf.train.SummaryWriter(dev_summary_dir, sess.graph) 103 | 104 | # Checkpoint directory. Tensorflow assumes this directory already exists so we need to create it 105 | checkpoint_dir = os.path.abspath(os.path.join(out_dir, "checkpoints")) 106 | checkpoint_prefix = os.path.join(checkpoint_dir, "model") 107 | if not os.path.exists(checkpoint_dir): 108 | os.makedirs(checkpoint_dir) 109 | saver = tf.train.Saver(tf.all_variables()) 110 | 111 | # Initialize all variables 112 | sess.run(tf.initialize_all_variables()) 113 | 114 | cnn.outputnetwork.print_layers() 115 | 116 | 117 | def train_step(x_batch, y_batch): 118 | """ 119 | A single training step 120 | """ 121 | pad=np.zeros([len(x_batch),1,x_train.shape[2],1],dtype=np.float32) 122 | 123 | feed_dict = { 124 | cnn.input_x: x_batch, 125 | cnn.input_y: y_batch, 126 | cnn.pad:pad 127 | # cnn.dropout_keep_prob: FLAGS.dropout_keep_prob 128 | } 129 | # enable noise layers 130 | feed_dict.update(cnn.outputnetwork.all_drop) 131 | _, step, summaries, loss, accuracy = sess.run( 132 | [train_op, global_step, train_summary_op, cnn.loss, cnn.accuracy], 133 | feed_dict) 134 | # tl.files.save_npz(outputnetwork.all_drop,name="outputwork.npz") 135 | time_str = datetime.datetime.now().isoformat() 136 | print("{}: step {}, loss {:g}, acc {:g}".format(time_str, step, loss, accuracy)) 137 | train_summary_writer.add_summary(summaries, step) 138 | 139 | 140 | 141 | def dev_step(x_batch, y_batch, writer=None): 142 | """ 143 | Evaluates model on a dev set 144 | """ 145 | # disable noise layers 146 | pad = np.zeros([x_batch.shape[0], 1, x_train.shape[2], 1]) 147 | dp_dict = tl.utils.dict_to_one(cnn.outputnetwork.all_drop) 148 | feed_dict = { 149 | cnn.input_x: x_batch, 150 | cnn.input_y: y_batch, 151 | cnn.pad:pad 152 | # cnn.dropout_keep_prob: FLAGS.dropout_keep_prob 153 | } 154 | feed_dict.update(dp_dict) 155 | step, summaries, loss, accuracy = sess.run( 156 | [global_step, dev_summary_op, cnn.loss, cnn.accuracy], 157 | feed_dict) 158 | time_str = datetime.datetime.now().isoformat() 159 | print("{}: step {}, loss {:g}, acc {:g}".format(time_str, step, loss, accuracy)) 160 | if writer: 161 | writer.add_summary(summaries, step) 162 | 163 | # Generate batches 164 | batches = data_helpers.batch_iter( 165 | list(zip(x_train, y_train)), FLAGS.batch_size, FLAGS.num_epochs) 166 | # Training loop. For each batch... 167 | for batch in batches: 168 | x_batch, y_batch = zip(*batch) 169 | train_step(x_batch, y_batch) 170 | current_step = tf.train.global_step(sess, global_step) 171 | if current_step % FLAGS.evaluate_every == 0: 172 | print("\nEvaluation:") 173 | dev_step(x_dev, y_dev, writer=dev_summary_writer) 174 | print("") 175 | if current_step % FLAGS.checkpoint_every == 0: 176 | path = saver.save(sess, checkpoint_prefix, global_step=current_step) 177 | print("Saved model checkpoint to {}\n".format(path)) 178 | --------------------------------------------------------------------------------