tensorflow入门笔记

Session 会话控制

with tf.Session as sess这样就不用sess.close()了。

前期定义的那些参数变量,还没有激活,sess.run(参数名)相当于有了一个指针指向某个参数,使之执行那条语句(激活)(才能输出变量值)。

# method 1
sess = tf.Session()
result = sess.run(product)
print(result)
sess.close()

# method 2
with tf.Session() as sess:
    result2 = sess.run(product)
    print(result2)

tf.constant

matrix1=tf.constant([[3,3]]) #一个一行两列的参数变量
matrix2=tf.constant([[2],[2]]) #一个一列两行的参数变量

placeholder

想在sess.run(output, feed_dict={input1: [7.], input2: [2.]})))即想在sess.run里传进参数。

xs = tf.placeholder(tf.float32, [None, 1])先定义一个 (n行1列)
占个位置,None代表无论输入有多少都可以,因为输入只有一个特征,所以这里是1。

这里sess.run(xs,{xs,[[1],[2]]})要这样输入,输入的是列向量。

后面才会赋值,就是在sess.run(train_step, feed_dict={xs: x_data, ys: y_data})

Variable变量

通过tf.Variable()创建变量 Tensor 时需要设置一个初始值,但这个初始值并不能立即使用。变量 Tensor 需要经过下面的 init 过程后才能使用:

# 初始化变量
init = tf.global_variables_initializer()
sess.run(init)

几个神经元

x=np.linspace(-1,1,300)[:,np.newaxis]输出一个300*1的矩阵,只有一个神经元。300个例子

激活函数、激励函数

例如一个神经元对猫的眼睛敏感,那当它看到猫的眼睛的时候,就被激励了,相应的参数就会被调优,它的贡献就会越大。

想象softmanx的图像,不同x对应不同y。激励不同。

softmax:常用于分类问题;relu:常用于回归问题

minst数据表示

比如y=[0 0 1 0 0 0 0 0 0 0] 第三位是1,表示数字2

类似的有:https://morvanzhou.github.io/tutorials/machine-learning/tensorflow/5-02-dropout/

y = digits.target
y = LabelBinarizer().fit_transform(y)

卷积

卷积过程需要用到卷积核,可以理解为一个二维的滑动窗口,每个卷积核由nm(长宽)个小格组成,每个小格都有自己的权重值,卷积过程就是将卷积核覆盖的像素值乘以对应格子内的系数求和得到一个新的值,由于将n*m个点压缩成一个点,所以长宽会变小,每个卷积核扫描完后产生一层图像,多个卷积核就产生多层,这样高度就会增加

系统问题

Spyder设置自动补全(按tab不自动补全了)

  1. Mac下修改:/Users/apple/anaconda3/lib/python3.6/site-packages/spyder/utils/introspection/module_completion.py
    找到第279行,最后增加一个’tensorflow’
  2. 重启spyder。
  3. spyder 代码自动补齐设置方式
    在tools->preferences->IPython console->advanced Settings 下面,把User the greedy completer 勾选上,
    再把Autocall 选 Full
  4. conda uninstall enum34

基础知识

张量(Tensor)

[[[1., 2., 3.]], [[7., 8., 9.]]]        # 这个 3 阶张量就是三维数组,shape=[2, 1, 3]
t3 = tf.constant([[[5], [6], [7]], [[4], [3], [2]]])    # 创建一个 2x3x1 数组,即 3 阶张量,数据类型默认为整型

yl:第一维是行数 第二维是列数(按最小[]计算), 第三维是每个最小[]里的个数。
每次遇到]就是换行

加法 = 在末尾添加

n1*m + n2*m = (n1 + n2)*m 比如x=[[1,1],[2,2],[3,3]],y=[[6,6],[5,5]],那么x+y=[[1, 1], [2, 2], [3, 3], [6, 6], [5, 5]]

np.random.shuffle 打乱顺序函数

tf.assign

tf.assign(ref, value, validate_shape=None, use_locking=None, name=None)函数完成了将value赋值给ref的作用。

其中:ref 必须是tf.Variable创建的tensor,如果ref=tf.constant()会报错!同时,shape(value)==shape(ref)

举例说明:

import tensorflow as tf
A = tf.Variable([1,2,3])
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print (sess.run(A))     ## [1,2,3]
    sess.run(tf.assign(A, [1,2,5]))
    print (sess.run(A))

tf.app.flags.FLAGS

命令行执行程序时,需要传些参数

import tensorflow as tf

tf.app.flags.DEFINE_string('recipe', 'aaa', 'The directory containing the recipe') # 第一个参数 是方法名,第二个是默认值,第三个是对方法的说明(不会传入)
 
FLAGS = tf.app.flags.FLAGS  #对象实例

flag_recipe = FLAGS.recipe  # print(flag_recipe) 为aaa(默认设的值)。

# 比如这个py文件名叫a.py,执行 python a.py --recipe='abcde',则flag_recipe = 'abcde'

tensorflow三种读取数据方式

入门:https://zhuanlan.zhihu.com/p/27238630

参考 https://blog.csdn.net/zzk1995/article/details/54292859

第一种:feed_dict,这种方法在画graph的时候使用placeholder来站位,在真正run的时候通过feed字典把真实的输入传进去。

第二种:队列读取:

  1. tf.train.string_input_producer函数把我们需要的全部文件打包为一个tf内部的queue类型,之后tf开文件就从这个queue中取目录了

    files_in = ["./data/data_batch%d.bin" % i for i in range(1, 6)]
    files = tf.train.string_input_producer(files_in)

  2. 搞一个reader,不同reader对应不同的文件结构,reader相当于一个每次能读取一段数据的搬运工,数据打包成一个queue目录,放在一个地方,reader是搬运工,每个搬一些数据(特征,input)进来。

    reader = tf.FixedLengthRecordReader(record_bytes=1+32323)

  3. 用reader的read方法,这个方法需要一个IO类型的参数,就是我们上边string_input_producer输出的那个queue了,reader从这个queue中取一个文件目录,然后打开它经行一次读取,reader的返回是一个tensor(这一点很重要,我们现在写的这些读取代码并不是真的在读数据,还是在画graph,和定义神经网络是一样的,这时候的操作在run之前都不会执行,这个返回的tensor也没有值,他仅仅代表graph中的一个结点

    key, value = reader.read(files)

  4. 对这个tensor做些数据与处理,比如CIFAR1-10中label和image数据是糅在一起的,这里用slice把他们切开,切成两个tensor

  5. 用tf.train.batch或者tf.train.shuffle_batch这个函数把一个一个小样本的tensor打包成一个高一维度的样本batch

  6. 5.事实上一直到上一部的images这个tensor,都还没有真实的数据在里边,我们必须用Session run一下这个4D的tensor,才会真的有数据出来。这个原理就和我们定义好的神经网络run一下出结果一样,你一run这个4D tensor,他就会顺着自己的operator找自己依赖的其他tensor,一路最后找到最开始reader那里。

tf.train.string_input_producer → reader → tf.train.batch/tf.train.shuffle_batch

tensorflow构建矩阵

bucket:在gpu cuda运算都是矩阵运算,构建矩阵,维度为batch_sizelengthdim,这个length是一批中最长的那个值,比如有5个text,长度分别为2,12,20,25,13,则length为25,那么构建的矩阵就为32255000,长度不足的,会padding补0补齐,这样对于长度小的,就不值得了,白计算了。所以先按由长至短排序,长的和长的在一起,短的和短的在一起。tensorflow中,bucket就是做这个的,设置bucket值,比如10,就是按大小分成10团。

logits

输出,也就是预测值

mnist机器学习入门

参考 http://wiki.jikexueyuan.com/project/tensorflow-zh/tutorials/mnist_beginners.htmlhttp://wiki.jikexueyuan.com/project/tensorflow-zh/tutorials/mnist_pros.html

import tensorflow as tf

import tensorflow.examples.tutorials.mnist.input_data as input_data
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)  # mnist是一个轻量级的类。它以Numpy数组的形式存储着训练、校验和测试数据集。同时提供了一个函数,用于在迭代中获得minibatch

x = tf.placeholder(tf.float32,[None, 784])

W = tf.Variable(tf.zeros([784, 10]))
b = tf.Variable(tf.zeros([10]))
y = tf.nn.softmax(tf.matmul(x, W) + b)
y_ = tf.placeholder("float", [None, 10])

cross_entropy = -tf.reduce_mean(y_*tf.log(y))   # tf.reduce_sum把minibatch里的每张图片的交叉熵值都加起来了。我们计算的交叉熵是指整个minibatch的

train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy) # 这一行代码实际上是用来往计算图上添加一个新操作,其中包括计算梯度,计算每个参数的步长变化,并且计算出新的参数值。  返回的train_step操作对象,在运行时会使用梯度下降来更新参数。因此,整个模型的训练可以通过反复地运行train_step来完成。0.01:学习率

init = tf.initialize_all_variables()

sess = tf.Session()
sess.run(init)

for i in range(1000):
    batch_xs, batch_ys = mnist.train.next_batch(100)    # 会随机抓取训练数据中的100个批处理数据点,然后我们用这些数据点作为参数替换之前的占位符来运行train_step
    sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys})  # 每一步迭代,我们都会加载100个训练样本,然后执行一次train_step,并通过feed_dict将x 和 y_张量占位符用训练训练数据替代。train.next是真实的值参与,所以batch_ys对应的是 y_

correct_prediction = tf.equal(tf.argmax(y,1),tf.argmax(y_,1))

accuracy = tf.reduce_mean(tf.cast(correct_prediction,"float"))

print(sess.run(accuracy, feed_dict={x: mnist.test.images, y_: mnist.test.labels}))

注意:

  1. mnist是一个轻量级的类。它以Numpy数组的形式存储着训练、校验和测试数据集。同时提供了一个函数,用于在迭代中获得minibatch
  2. mnist.train.next_batch(100) :会随机抓取训练数据中的100个批处理数据点,然后我们用这些数据点作为参数替换之前的占位符来运行train_step,train.next是真实的值参与,所以batch_ys对应的是 y_。
  3. tf.reduce_sum把minibatch里的每张图片的交叉熵值都加起来了。我们计算的交叉熵是指整个minibatch的
  4. 每一步迭代,我们都会加载100个训练样本,然后执行一次train_step,并通过feed_dict将x 和 y_张量占位符用训练训练数据替代。
  5. 在计算图中,你可以用feed_dict来替代任何张量,并不仅限于替换占位符

tf.reshape

tf.reshape(h_pool2, [-1, 7*7*64]) :把h_pool2的shape变为 N行,7*7*64列。

深入MNIST

参考 http://wiki.jikexueyuan.com/project/tensorflow-zh/tutorials/mnist_pros.html

加入了卷积层,激活函数,池化层,dropout(2层卷积层 1层全连接层)。

variable的初始化有所不同了(从上面用zeros变为初始化正态分布)。(为了创建这个模型,我们需要创建大量的权重和偏置项。这个模型中的权重在初始化时应该加入少量的噪声来打破对称性以及避免0梯度。由于我们使用的是ReLU神经元,因此比较好的做法是用一个较小的正数来初始化偏置项,以避免神经元节点输出恒为0的问题(dead neurons)。为了不在建立模型的时候反复做初始化操作,我们定义两个函数用于初始化。)

# load MNIST data

import tensorflow.examples.tutorials.mnist.input_data as input_data
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)

# start tensorflow interactiveSession
import tensorflow as tf
sess = tf.InteractiveSession()

# weight initialization
def weight_variable(shape):
    initial = tf.truncated_normal(shape, stddev=0.1)
    return tf.Variable(initial)

def bias_variable(shape):
    initial = tf.constant(0.1, shape = shape)
    return tf.Variable(initial)

# convolution
def conv2d(x, W):
    return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')
# pooling
def max_pool_2x2(x):
    return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')

# Create the model
# placeholder
x = tf.placeholder("float", [None, 784])
y_ = tf.placeholder("float", [None, 10])
# variables

""" # 之前的
W = tf.Variable(tf.zeros([784,10]))
b = tf.Variable(tf.zeros([10]))

y = tf.nn.softmax(tf.matmul(x,W) + b)
""" 

# first convolutinal layer
w_conv1 = weight_variable([5, 5, 1, 32])
b_conv1 = bias_variable([32])

x_image = tf.reshape(x, [-1, 28, 28, 1])

h_conv1 = tf.nn.relu(conv2d(x_image, w_conv1) + b_conv1)
h_pool1 = max_pool_2x2(h_conv1)

# second convolutional layer
w_conv2 = weight_variable([5, 5, 32, 64])
b_conv2 = bias_variable([64])

h_conv2 = tf.nn.relu(conv2d(h_pool1, w_conv2) + b_conv2)
h_pool2 = max_pool_2x2(h_conv2)

# densely connected layer
w_fc1 = weight_variable([7*7*64, 1024])
b_fc1 = bias_variable([1024])

h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64])
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, w_fc1) + b_fc1)

# dropout
keep_prob = tf.placeholder("float")
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)

# readout layer
w_fc2 = weight_variable([1024, 10])
b_fc2 = bias_variable([10])

y_conv = tf.nn.softmax(tf.matmul(h_fc1_drop, w_fc2) + b_fc2)

# train and evaluate the model
cross_entropy = -tf.reduce_sum(y_*tf.log(y_conv))
train_step = tf.train.AdagradOptimizer(1e-4).minimize(cross_entropy)
correct_prediction = tf.equal(tf.argmax(y_conv, 1), tf.argmax(y_, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
sess.run(tf.initialize_all_variables())
for i in range(20000):
    batch = mnist.train.next_batch(50)
    if i%100 == 0:
        train_accuracy = accuracy.eval(feed_dict={x:batch[0], y_:batch[1], keep_prob:1.0})
        print ("step %d, train accuracy %g" %(i, train_accuracy))
    train_step.run(feed_dict={x:batch[0], y_:batch[1], keep_prob:0.5})

print ("test accuracy %g" % accuracy.eval(feed_dict={x:mnist.test.images, y_:mnist.test.labels, keep_prob:1.0}))

TensorFlow运作方式入门

参考 http://wiki.jikexueyuan.com/project/tensorflow-zh/tutorials/mnist_tf.html

用到了两个python程序:

文件目的
mnist.py构建一个完全连接(fully connected)的MINST模型所需的代码。
fully_connected_feed.py利用下载的数据集训练构建好的MNIST模型的主要代码,以数据反馈字典(feed dictionary)的形式作为输入模型。

路径在D:\Softwave\Anaconda\Lib\site-packages\tensorflow\examples\tutorials\mnist

只需要直接运行fully_connected_feed.py文件,就可以开始训练。

运行的时候会抱错说找不到tmp folder. 这是因为在一般Python都是在Linux下面, 在Windows下面盘符不存在,修改下

default=os.path.join(os.getenv('TEST_TMPDIR', '/tmp') 
# 改为:
default=os.path.join(os.getenv('TEST_TMPDIR', 'D:\\'),

990001201901040071

测试sess.run:

import tensorflow as tf

#labels = tf.placeholder(tf.int32, shape=(batch_size))
labels = tf.constant([1, 5, 5, 5, 5, 5, 7]) # 或加上name,labels = tf.constant([1, 2, 3, 4, 5, 6, 7],name = "labels")

batch_size = tf.size(labels)

labelss = tf.expand_dims(labels, 1) #变成一列的二维矩阵,如果是0,就是变成一行的二维矩阵

indices = tf.expand_dims(tf.range(0, batch_size, 1), 1) #按列,变成从0开始的[[0],[1],[2],[3],[4],[5],[6]]

#concated = tf.concat(1, [indices, labelss])
global_step = tf.Variable(0, name='global_step', trainable=False)   # 变量 初值为 0

sess = tf.InteractiveSession()
sess.run(tf.global_variables_initializer()) #变量只能在这里sess.run显示,下面又是新建的session

print(sess.run(global_step))

with tf.Session() as sess:
    print(sess.run(labelss))    # [[1],[5],[5],[5],[5],[5],[7]]
    print("labelss",labelss)    # 不管之前是不是run了,只要直接print的话,就只会输出格式。Tensor("ExpandDims_1:0", shape=(7, 1), dtype=int32) 
    print(sess.run(labels))     # [1 5 5 5 5 5 7]
    print("labels",labels)      # Tensor("Const_1:0", shape=(7,), dtype=int32)
    print(sess.run(batch_size)) # 7
    print("batch_size", batch_size)           # Tensor("Size_1:0", shape=(), dtype=int32)     前面的Size_1是name
    print(sess.run(indices))    # [[0],[1],[2],[3],[4],[5],[6]]
    print("indices",indices)              # Tensor("ExpandDims_10:0", shape=(7, 1), dtype=int32)
    #或者写成 labelss_,labels_,batch_size_,indices_ = sess.run(labelss, labels, batch_size, indices)
    #print(sess.run(concated))
    #print(concated)

mnist.py

线性softmax连接(softmax_linear)。(之前学习的叫做非线性softmax (ei/累加e…))

#Linear
with tf.name_scope('softmax_linear'):
weights = tf.Variable(
    tf.truncated_normal([hidden2_units, NUM_CLASSES],
                        stddev=1.0 / math.sqrt(float(hidden2_units))),
    name='weights')
biases = tf.Variable(tf.zeros([NUM_CLASSES]),
                     name='biases')
logits = tf.matmul(hidden2, weights) + biases

fill_feed_dict函数会查询给定的DataSet,索要下一批次batch_size的图像和标签,与占位符相匹配的Tensor则会包含下一批次的图像和标签。

 batch = mnist.train.next_batch(50) 
 或
 images_feed, labels_feed = data_set.next_batch(FLAGS.batch_size)

然后,以占位符为哈希键,创建一个Python字典对象,键值则是其代表的反馈Tensor。

feed_dict={x:batch[0], y_:batch[1], keep_prob:0.5}
或
feed_dict = {images_placeholder: images_feed,labels_placeholder: labels_feed,}

在运行sess.run函数时,要在代码中明确其需要获取的两个值:[train_op, loss]。# train_op = optimizer.minimize(loss, global_step=global_step)

Tensorflow 继续训练方法

参考 https://blog.csdn.net/u012968002/article/details/79884920

.meta文件保存了当前图结构

.index文件保存了当前参数名

.data文件保存了当前参数值

参考 https://blog.csdn.net/lovelyaiq/article/details/78646401

把/home/yelong/anaconda2/lib/python2.7/site-packages/tensorflow/python/training/saver.py中的max_to_keep=5改为10.这样可以多保存一些model。

tensorboard

http://localhost:6006

with tf.name_scope(’…’),下属的都在这个名字,比如下面,就是layer/weights。。之后看可视化的图,也是在一个框架里。

with tf.name_scope('layer'):
    with tf.name_scope('weights'): # layer/weights
        Weights = tf.Variable(tf.random_normal([in_size, out_size]), name='W')

writer = tf.summary.FileWriter("logs/", sess.graph)writer = tf.train.SummaryWriter('logs/', sess.graph):把整个框架加载到文件(events.out…)中去,之后才能从文件中加载出来,从浏览器中打开。

举例:莫烦python:https://morvanzhou.github.io/tutorials/machine-learning/tensorflow/4-1-tensorboard1/

from __future__ import print_function
import tensorflow as tf


def add_layer(inputs, in_size, out_size, activation_function=None):
    # add one more layer and return the output of this layer
    with tf.name_scope('layer'):
        with tf.name_scope('weights'):
            Weights = tf.Variable(tf.random_normal([in_size, out_size]), name='W')
        with tf.name_scope('biases'):
            biases = tf.Variable(tf.zeros([1, out_size]) + 0.1, name='b')
        with tf.name_scope('Wx_plus_b'):
            Wx_plus_b = tf.add(tf.matmul(inputs, Weights), biases)
        if activation_function is None:
            outputs = Wx_plus_b
        else:
            outputs = activation_function(Wx_plus_b, )
        return outputs


# define placeholder for inputs to network
with tf.name_scope('inputs'):
    xs = tf.placeholder(tf.float32, [None, 1], name='x_input')
    ys = tf.placeholder(tf.float32, [None, 1], name='y_input')

# add hidden layer
l1 = add_layer(xs, 1, 10, activation_function=tf.nn.relu)
# add output layer
prediction = add_layer(l1, 10, 1, activation_function=None)

# the error between prediciton and real data
with tf.name_scope('loss'):
    loss = tf.reduce_mean(tf.reduce_sum(tf.square(ys - prediction),
                                        reduction_indices=[1]))

with tf.name_scope('train'):
    train_step = tf.train.GradientDescentOptimizer(0.1).minimize(loss)

sess = tf.Session()

# tf.train.SummaryWriter soon be deprecated, use following
if int((tf.__version__).split('.')[1]) < 12 and int((tf.__version__).split('.')[0]) < 1:  # tensorflow version < 0.12
    writer = tf.train.SummaryWriter('logs/', sess.graph)
else: # tensorflow version >= 0.12
    writer = tf.summary.FileWriter("logs/", sess.graph)

# tf.initialize_all_variables() no long valid from
# 2017-03-02 if using tensorflow >= 0.12
if int((tf.__version__).split('.')[1]) < 12 and int((tf.__version__).split('.')[0]) < 1:
    init = tf.initialize_all_variables()
else:
    init = tf.global_variables_initializer()
sess.run(init)

# direct to the local dir and run this in terminal:
# $ tensorboard --logdir=logs

莫烦python:https://morvanzhou.github.io/tutorials/machine-learning/tensorflow/4-2-tensorboard2/

add_summary:每隔多少步,添加进一个点

tf.summary.scalar(‘loss’, loss):loss的summary不是用histogram,而是用scalar。

TensorFlow 图表有两种连接关系:数据依赖和控制依赖。数据依赖显示两个操作之间的tensor流程,用实心箭头指示,而控制依赖用点线表示。

数据读取

数据读取

从文件读取数据

一共典型的文件读取管线会包含下面这些步骤:

  1. 文件名列表
  2. 可配置的 文件名乱序(shuffling)
  3. 可配置的 最大训练迭代数(epoch limit)
  4. 文件名队列
  5. 针对输入文件格式的阅读器
  6. 纪录解析器
  7. 可配置的预处理器
  8. 样本队列

。。。看蒙了

先创建数据流图,这个数据流图由一些流水线的阶段组成,阶段间用队列连接在一起。第一阶段将生成文件名,我们读取这些文件名并且把他们排到文件名队列中。第二阶段从文件中读取数据(使用Reader),产生样本,而且把样本放在一个样本队列中。根据你的设置,实际上也可以拷贝第二阶段的样本,使得他们相互独立,这样就可以从多个文件中并行读取。在第二阶段的最后是一个排队操作,就是入队到队列中去,在下一阶段出队。因为我们是要开始运行这些入队操作的线程,所以我们的训练循环会使得样本队列中的样本不断地出队。

timeline

在本地可以。

在服务器出现报错:
Non-OK-status: status_ status: Failed precondition: could not dlopen DSO: libcupti.so.8.0; dlerror: libcupti.so.8.0: cannot open shared object file: No such file or directory
已放弃 (core dumped)

此时需要把/usr/local/cuda/extras/CUPTI/lib64/ 添加到 LD_LIBRARY_PATH:

vi ~/.bashrc # 在bashrc中添加进
export LD_LIBRARY_PATH=/usr/local/cuda/extras/CUPTI/lib64:$LD_LIBRARY_PATH
source ~/.bashrc

举例子:

import os
import tensorflow as tf
from tensorflow.python.client import timeline

a = tf.random_normal([2000, 5000])
b = tf.random_normal([5000, 1000])
res = tf.matmul(a, b)

config = tf.ConfigProto()
config.gpu_options.allow_growth = True  #让gpu运行,而不是在cpu运行
with tf.Session() as sess:
    # add additional options to trace the session execution
    options = tf.RunOptions(trace_level=tf.RunOptions.FULL_TRACE)
    run_metadata = tf.RunMetadata()
    sess.run(res, options=options, run_metadata=run_metadata)

    # Create the Timeline object, and write it to a json file
    fetched_timeline = timeline.Timeline(run_metadata.step_stats)
    chrome_trace = fetched_timeline.generate_chrome_trace_format()
    global_step = 0
    with open(os.path.join('/data/yelong/timeline','timeline','timeline_step_%d.json' % global_step), 'w') as f:
        f.write(chrome_trace)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值