深度学习框架-----Tensorflow2基础

一、基础概念

1、深度学习框架基础概念

深度学习框架的出现降低了入的槛。我们不在需要丛从复杂的神经网络和反向传播算法开始编代码,可以依据需要,使用已有的模型配置参数,而模型的参数自动训练得到。我们也可以在已有模型的基础上增加自定义网络层,或者是在顶端选择自己需要的分类器和优化算法

一个深度学习框架可以理解为一套积木。积木中的每个组件就是一个模型或者算法。这就可以群免重复造轮子,我代可以使用积木中的组生去组装符合要求的积木模型。

2、主流深度学习框架tensorflow2基础

来源

TensorFlow是谷歌开源的第二代用于数字计算的软件库。TensorFlow计算框架可以很好地支持深度学习的各种算法,可以支持多种计算平台,系统稳定性较高。

特点

在这里插入图片描述

与1.x版本比tensorflow2.0的特点

Tensorflow2特点:

  • Keras高级接口:
    最大的特性(Easytouse):去掉了graph和session机制。变的像Python,Pytorch一样所见即所得。

  • 主要改进点:

    • TensorFlow2的核心功能是动态图机制Eagerexecution。它允许用启像正常程序一样去编写、调试模
      型,使TensorFlow更易于学习和应用;

    • 支持更多平台、更多语言,通过标准化AP的交换格式和提供准线改善这些组件之间的兼容性:

    • 删除已弃用的AP并减少重复的AP数,避免给用户造成混淆;

    • 兼容性和连续性:兼容1.x模块

    • t.cntrib退出历史舞台。其中有维护价值的模块会被移动到别的地方,剩余的都将被册删除。

分布式

  • TensorFlow在不同计算机上运行
    • 小到智能机,大到集群扩展,可以立刻生成模型
  • 目前原生支持的分布式深度学习框架不多,只有TensorFlow、CNTK、DeepLearning4J、MXNet等。
  • 在单GPU的条件下,绝大多数深度学习框架都依赖于cuDNN,因此只要硬件计算能力或者内存分配差异
    不大,最终训练速度不会相差太大。但是对于大规模深度学习来说,巨大的数据量使得单机很难在有
    限的时间完成训练。而Tensorflaw支持分布式训练。

3、张量介绍

在这里插入图片描述

4、tensorflow2 Eager Execution VS Auto Graph

4.1 Eager Execution
  • 静态图:采用静态图(模式)的即s可正w,通过计算图将计算的定义和热行分隔升,这是-种声明式(declarative)的编程模型。Graph模式下,需要先构建og命计算图然后开启对话(sesSsion),再喂进数据才能得到执行结果。
  • 这种静态图在分布式训练,性能优化和部署方面有很多优势。但是在de叫g时确实非常不方 更,类似以于对编译好的语言程序调用,此时是我们无法对其进行内部的调试,因此有了基 于动态计算图的EagerExecutiog
  • EagerExecution是一种命令式编程,和原生python一致。当执行某个操作时立即返回结果。
  • TensorFlow2.0默认采用EaqerExecution模式。
4.2 Auto Graph
  • 在TensorFlow2中,默认情况下启用了Eager Execution 。对于用户而言直观且灵活(运行 一次性操作更容易,更快),但这可能会牲性能和可部署性。
  • 要获得最佳性能开使模型可在任何地方部著,可以使用添加装饰器t.uncti叫从程序中构建图,可以使得Python代码更高效。
  • tf.function可以将函数中的fersorFlow操作构建为一个Graphep9这个函数就可以在graph模式9o908
    下执行。可以看成函数被封装成了一个Graph的TensorFlow操作。

二、Tensorflow2基础操作

1、张量的创建

1.1创建常量的tensor

1.创建常见常量tensor

import tensorflow as tf 
import numpy as np
const_a = tf.constant([[1,2,3,4]],shape=[2,2],dtype=tf.float32)  #创建2x2矩阵
const_a

########################输出结果################################
<tf.Tensor: shape=(2, 2), dtype=float32, numpy=
array([[1., 2.],
       [3., 4.]], dtype=float32)>

2.创建全零或者全一的

zero_b = tf.zeros(shape=[2,2],dtype=tf.int32)
zero_b
#tf.zeros_like(),tf.ones(),tf.ones_like();

<tf.Tensor: shape=(2, 2), dtype=int32, numpy=
array([[0, 0],
       [0, 0]])>

3.自定义数值

fill_c = tf.fill([3,3],8);
fill_c
fill_c.numpy()


array([[8, 8, 8],
       [8, 8, 8],
       [8, 8, 8]])

4.已知分布

randm_d = tf.random.normal([5,5],mean=0,stddev=1.0);
randm_d.numpy()

array([[ 0.09472452,  1.0340148 , -0.6786982 ,  1.0869443 ,  0.3258813 ],
       [-0.77133644,  0.83533937,  1.2375485 , -1.3813246 , -0.48714033],
       [ 1.6331278 ,  1.5953207 , -0.13377142,  0.4633193 ,  1.2541134 ],
       [ 1.691077  , -2.1534183 ,  0.13208625,  0.47703937, -0.94133264],
       [-2.6030612 , -2.0240393 , -0.5370001 ,  0.3690688 , -0.32192004]],
      dtype=float32)

5.从numpy,list对象创建

list_e = [1,2,3,4,5]
type(list_e)
tensor_e = tf.convert_to_tensor(list_e,dtype=tf.float32)
tensor_e

<tf.Tensor: shape=(5,), dtype=float32, numpy=array([1., 2., 3., 4., 5.], dtype=float32)>
1.2创建变量的tensor
var1 = tf.Variable(tf.ones([2,3]))
var1

#变量数值读取
print(var1.read_value())
value1 = [[1,2,3],[4,5,6]]
var1.assign(value1)

tf.Tensor(
[[1. 1. 1.]
 [1. 1. 1.]], shape=(2, 3), dtype=float32)
<tf.Variable 'UnreadVariable' shape=(2, 3) dtype=float32, numpy=
array([[1., 2., 3.],
       [4., 5., 6.]], dtype=float32)>

2、张量的索引与切片

2.1 tensor 的索引

索引的基本格式:a[d1] [d2] [d3]

#创建一个4维tensor。tensor包含4张图片,每张图片的大小为100*100*3。NHWC
tensor_h = tf.readom.normal([4,100,100,3])
tensor_h

取出第一张图片第二通道中在[20,40]位置的像素点

tensor_h[0][19][39][1]

如果要提取的索引不连续,在tensorflow里面的用法就是要用到tf.gather和tf.gather_nd

在某一维度进行索引。tf.gather(params,indices,axis=None)

params:输入张量

indices:取出数据的索引

axis:所取数据所在维度

#取出tensor_h([4,100,100,37)中,第1,2,4张图像。
indices = [0,1,3]
tf.gather(tensor_h,axis=0,indices=indices,batch_dims=l)

tf.gather_nd允许在多维上进行索引l:tf.gather_nd(params,indices) params:输入张量; indices:取出数据的索引,一般为多维列表。

#取出tensoth(4.100.100.37)中,第一张图像第一个维度中[1,1]的像素点:第二张图片第一维度中[2,2]的像素点 
indices = [[0, 1,1,0], [1,2,2,0]] 
tf.gathernd(tensorh,indices=indices) 

2.2 tensor 切片

[start:end]:从tensor的开始位置到结束位置的数据切片;
[start:end:step]或者[::step]:从tensor的开始位置到结束位置每隔step的数据切片;
[::-1]:负数表示倒序切片:
‘…’:任意长;

tensor_h

#每两张图片取出一张的切片
tesnsor_h[::2,...]

#倒叙切片
tensor_h[::-1]

3、张量的维度变换

3.1维度查看
const_d_1=tf.constant([[1,2,3,4]],shape=[2,2],dtype=tf.float32 
井查看维度常用的三种方式 
y1329090876 
print(const_d_l.shape) 
print(const_d_1.get_shape()) 
print(tf.shape(constd1)#输出为张量,其数值表示的是所查看张量维度大小 

可以看出.shape和.get_shape()都是返回TensorShape类型对象,而tf.shape(x)返回的是Tensor类型对象

3.2维度的重组

tf.reshape(tensor,shape,name=None):
tensor:输入张量;
shape:重组后张量的维度。

reshape_1=tf.constant([[1,2,3],[4,5,6]]) 
print(reshape_1) 
tf.reshape(reshape_1, (3,2) 

3.3维度增加

tf.expand dims(input,axis,name=None):
input:输入张量;
axis:在第axis维度后增加一个维度。在输入D尺寸的情况下,轴必须在[-(D+1),D】(含)范围内。负数代表倒序

#生成一个大小为100*100*3的张量来表示一张尺寸为100*100的三通道彩色图片 
expand_sample_1 = tf.random.normal([100,100,3]) 
print("原始数据尺寸:",expand_sample_1.shape) 
print("在第一个维度前增加一个维度(axis=0):"tf.expand_dims(expand_sample_l,axis=0).shape) 
print("在第二个维度前增加一个维度(axis=1):",tf.expand_dims(expand_sample_1,axis=1).shape) 

3.4维度减少

tf.squeeze(input,axis=None,name=None)
input:2输入张量;
axis:axis=1,表示要删掉的为1的维度。

#生成一个大小为100*100*3的张量来表示一张尺寸为100*100的三通道彩 
squeeze_sample_1=tf.random.normal([1,100,100,3]) 
print("原始数据尺寸:",squeeze_sample_1.shape) 
squeezed_sample_1=tf.squeeze(squeeze_sample_l,axis=0) 
print("维度压缩后的数据尺寸:",squeezed_sample_1.shape) 

3.5转置

tf.transpose(a,perm=None,conjugate=False,name=transpose)
a:输入张量;
perm:张量的尺寸排列;一般用于高维数组的转置。
conjugate:表示复数转置:
name:名称。

#低维的转置问题比较简单,输入需转置张量调用tf.transpose 
trans_sample_1=tf.constant([1,2,3,4,5,6]1.shape=[2.3] 
print"原始数据尺寸:",trans_sample_1.shape 
transposed_sample_l =tf.transpose(trans_sample_l) 
print"转置后数据尺寸:",transposed_sample_1.shape) 

对于一个三维张量来说,其原始的维度排列为[0,1,2](perm)分别代表高维数据的长宽高,
通过改变perm中数值的排列,可以对数据的对应维度进行转置

#生成一个大小为3*100*200*3的张量来表示4张尺寸为100*200的三通道彩色图片 
trans_sample_2=tf.random.normal([4,100,200,3]) 
print("原始数据尺寸:”,trans_sample_2.shape) 
#对4张图像的长宽进行对调。原始perm为[0,1,2,3],现变为[0,2,1,3] 
transposed_sample_2=tf.transpose(trans_sample_2,[0,2,1,3]) 
print("转置后数据尺寸:",transposed_sample_2.shape)
3.6广播(broadcast_to)

利用把broadcastto可以将小维度推广到大维度。 tf.broadcast_to(input,shape.name=None):
input:输入张量;
shape:输出张量的尺寸。

broadcast_sample_1=tf.constant([1,2,3,4,5,6]) 
print("原始数据:",broadcast_sample_1.numpy) 
broadcasted_sample_1=tf.broadcast.to(broadcast_sample_1,shape=[4,6]) 
print("广播后数据:",broadcasted_sample_l.numpy()) 

#运算时,当两个数组的形状不同时,与numpy一样,tensorf1ow将自动触发广播机制。 
a = tf.constant([[0,0,o],
[10,10,10],  
[20,20,20], 
[30,30,30]])
b = tf.constant([1,2,3]) 
print(a +b) 

4、张量的算数运算

4.1算术运算符

算术运算主要包括了:加(tf.add)、减(tf.subtract)、乘(tf.multiply)、除(tf.divide)、取对数(tf.math.log)和指数(tf.pow)等。

a=tf.constant([[3,5][4.8]]) 
b=tf.constant([[1,6],[2,9]]) 
print(tf.add(a,b)) 
4.2矩阵算法运算

矩阵乘法运算的实现通过调用tf.matmu

tf.matmu(a,b)
4.3张量的数据统计

张量的数据统计主要包括:
tf.reduce_min/max/mean():求解最小值最大值和均值函数:
tf.argmaxO/tf.argmin():求最大最小值位置:
tf.equal():逐个元素判断两个张量是否相等;
tf.unique():除去张量中的重复元素。
tf.nn.in_top_k(prediction,target,K):用于计算预测值和真是值是否相等,返回一个bool类型的张量。

下面演示tf.argmax(的用法:

返回最大值所在的下标
tf.argmax(input,axis):

  • input:输入张量;
  • axis:按照axis维度,输出最大值。
argmax_sample_1=tf.constant([[1,3],[2,5],[7,5]]) 
print("输入张量:",argmax_sample_1.numpy()"大小、",argmax_sample_1.shape) 
max_sample_1 = tf.argmax(argmax_sample_l,axis=0) 
max_sample_2 = tf.argmax(argmax_sample_l,axis=1) 
print("按列寻找最大值的位置:",max_sample_1.numpy()) 
print("按行寻找最大值的位置:"max_sample_2.numpy())

4.4基于维度的操作

tensorflow2中,tf.reduce_*一些列操作等造成张量维度的减少,这一系列操作都可以对一个张量在维度上的元素进行操作,如按行求平均,求取张量中所有元素的乘积等

常用的包括:

tf.reduce_sum(加法)

tf.reduce_prod(乘法)

tf.reduce_min(最小)

tf.reduce_max(最大)

tf.reduce_mean(均值)

tf.reduce_all(逻辑和)

tf.reduce_any(逻辑或)

tf.reduce_logsumexp(log(sum(exp)))操作)等。

这些操作的使用方法都相似,下面只演示tf.reducesum的操作案例。

计算一个张量的各个维度上元素的总和
tf.reduce_sum(input_tensor, axis=None, keepdims=False,name=None):

  • input_tensor:输入张量;
  • axis:指定需要计算的轴,如果不指定,则计算所有元素的均值;
  • keepdims:是否降维度,设置为True,输出的结果保持输入tensor的形状,设置为False,输出结果会降低维度;
  • name:操作名称。
reduce_sample_1=tf.constant([1,2,3,4,5,6],shape=[2,3]) 
print("原始数据",reduce_sample_1.numpy()"大小",reduce_sample_1.shape) 
print("按列计算,分别计算各列的和(axis=0):",tf.reduce_sum(reduce_sample_i,axis=0).numpy()) 
print("按行计算,分别计算各列的和(axis=1):",tf.reduce_sum(reduce_sample_1,axis=1).numpy())

5、张量的分割与合并

5.1张量的拼接

tensorflow中,张量拼接的操作主要包括:
tf.contact():将向量按指定维连起来,其余维度不变。
tf.stack():将一组R维张量变为R+1维张量,拼接前后维度变化。

tf.concat(values,axis,name=‘concat’):

  • values:输入张量;
  • axis:指定拼接维度;
  • name:操作名称。
concat_sample_1=tf.random.normal([4,100,100,3]) 
concat_sample_2=tf.random.normal([40,100,100,3])
print("拼接后数据的尺寸:",concat_sample_1.shape,concat_sample_2.shape)
concated_sample_1=tf.concat([concat_sample_1,concat_sample_2],axis=0) 
print("拼接后数据的尺寸:",concated_sample_1.shape) 

在原来矩阵基础上增加了一个维度,也是同样的道理,axis决定维度增加的位置

tf.stack(values,axis=o,name=‘stack’):

  • values:输入张量;一组相同形状和数据类型的张量。
  • axis:指定拼接维度;
  • name:操作名称。
stack_sample_1=tf.random.normal([100.100.3]) 
stack_sample_2=tf.random.normal1([100,100,3l]) 
print("原始数据的尺寸分别为:",stack_sample_1.shape,stack_sample_2.shape) 
进拼接后维度增加。axis=0,则在第一个维度前增加维度 
stackedsample_1=tf.stack([stack_sample.lstack_sample_2],axis=0) 
print("拼接后数据的尺寸:",stacked_sample_1.shape) 

5.2张良的分割

tensorflow中,张量分割的操作主要包括:

  • tf.unstack():将张量按照特定维度分解
  • tf.split():将张量按照特定维度划分为指定的分数。

与tf.unstack()相比,tf.split)更佳灵活。

tf.unstack(value,num=None,axis=0,name=‘unstack’):

  • value:输入张量;
  • num:表示输出含有num个元素的列表,num必须和指定维度内元素的个数相等。通常可以忽略不写这个参数。
  • axis:指明根据数据的哪个维度进行分割;y
  • name:操作名称。
#按照第一个维度对数据进行分解,分解后的数据以列表形式输出
tf.unstack(stacked_sample_1,axis=0)

tf.split(value,num_or_size_splits,axis=O):

  • value:输入张量;
  • num_or_size_splits:准备切成几份
  • axis:指明根据数据的那个维度进行分割

tf.split()的分割方式有两种

1.如果num_or_size_splits传入的是一个整数,那直接在axis=D这个维度上把张量平均切分成几个小张量。
2.如果num_or_size_splits传入的是一个向量,则在axis=D这个维度上把张量按照向量的元素值切分成几个小张量。

split_sample_1=tf.random.normal([10,100,100,3]) 
print("原始数据的尺寸为:",split_sample_1.shape) 
print("当num_or_size_splits=5,分割后数据的尺寸为:",np.shape(splited_sample_1)) 
splited_sample_2=tf.split(split_sample_l,num_or_size_splits=[3,5,2],axis=0) 
print("当num_or_size_splits=[3,5,2],分割后数据的尺寸分别为:" 
np.shape(splited_sample_2[0]),
np.shape(splited_sample_2[1]),             
np.shape(splited_sample_2[2])) 

6、张量的排序

tensorflow中,张量排序的操作主要包括:

  • tf.sort:按照升序或者降序对张量进行排序,返回排序后的张量。
  • tf.argsort():按照升序或者降序对张量进行排序,但返回的是索引。
  • tf.nn.top_k):返回前k个最大值。

tf.sort/argsort(input,direction,axis):

  • input:输入张量;
  • direction:排列顺序,可为DESCENDING降序或者ASCENDING(升序)。默认为ASCENDING(升序);
  • axis:按照axis维度进行排序。默认axis=-1最后一个维度。

tf.nn.top_k(input,sorted=TRUE):

  • input:输入张量;

  • K:需要输出的前k个值及其索引。

  • sorted:sorted=TRUE表示升序排列;sorted=FALSE表示降序排列。

    返回两个张量:

  • values:也就是每一行的最大的k个数字

  • indices:
    这里的下标是在输入的张量的最后一个维度的下标

sort_sample_1=tf.random.shuffle(tf.range(1o)) 
print("输入张量:",sort_sample_1.numpyO) 
sorted_sample_1=tf.sort(sort_sample_l,direction="ASCENDING") 
print("生序排列后的张量:",sorted_sample_1.numpyO) 
sorted_sample_2=tf.argsort(sort_sample_l,direction="ASCENDING") 
print("生序排列后,元素的索引",sorted_sample_2.numpy)

yalues,index=tf.nn.top_k(sort_sample_l,5) 
print("输入张量:",sort_sample_1numpy()) 
print("升序排列后的前5个数值:",values.numpy()) 
print("升序排列后的前5个数值的索引:",index.numpy())

三、Tensorflow2 Eager Execution模式

1、 eager execution模型

EagerExecution介绍:
TensorFlow的EagerExecution模式是一种命令式编程(imperativeprogramming),这和原生Python是一致的,当你执行某个操作时,可以立即返回结
果的。

Graph模式介绍:
TensorF1owl.0一直是采用Graph模式,即先构建一个计算图,然后需要开启session,喂进实际的数据才真正执行得到结果。
09087Eager Execution模式下,我们可以更容易debug代码,但是代码的执行效率更低。

xtf.ones((2,2),dtype=tf.dtypes.float32) 
y=tf.constant([[l, 2], 
[3,4]],dtype=tf.dtypes.float32) 
z= tf.matmul(x, y) 
print(z) 

#在tensorf1ow2.0版本中使用1.X版本的语法o可以使用2.0中的v1兼容包来沿用1.x代码,并在代码中关闭eager运算 
importtensorflow.compat.vl astf 
tf.disable_eager_executionO 
#创建graph,定义计算图 
a=tf.ones((2,2),dtype=tf.dtypes.float32) 
b=tf.constant([[,2], 
[3,4]],dtype=tf.dtypes.float32)
c=tf.matmul(a,b) 
#开启绘画,进行运算后,才能取出数据。 
with tf.SessionO as sess: 
print(sess.run(c)) 

Eager Execution模式的另一个优点可以使用python原生功能

importtensorflowastf 
thre9182tf.random.uniform([],0,1) 

x = tf.reshape(tf.range(0, 4), [2, 2]) 
print(thre_1) 
ifthre_1.numpy(>0.5: 
y = tf.matmul(x, x) 
else: 
y = tf.add(x, x)  

这种动态控制流主要得益于eager执行得到Tensor可以取出numpy值,这避免了使用Graph模式下的tf.cond和tf.while等算子

2、Tensorflow2.0 AutoGraph

当使用tf.function装饰器注释函数时,可以像调用任何其他函数一样调用它。它将被编译成图,这意味看可以获得更高效地在在GPU或TPU上运行。此时函数变成了一个tensorflow中的operation。我们可以直接调用函数,输出返回值,但是函数内部是在graph模式下执行的,无法直接查看中间变量数值

@tf.function 
def simple_nn_layer(w,x,b): 
print(b) 
return tf.nn.relu(tf.matmul(w,x)+b) 
 
w=tf.random.uniform((3,3)) 
x=tf.random.uniform((3,3)) 
b=tf.constant(0.5,dtype='float32') 
simple_nn_layer(w,x,b) 

通过输出结果可知,无法直接查看函数内部b的数值,而返回值可以通过.numpy()查看

通过执行一层cnn计算(相同操作),比较graph和eager execution模式的性能

#timeit测量小段代码的执行时间 
import timeit 
井创建一个卷积层。  
CNN_cell =tf.keras.layers.Conv2D(filters=100,kernel_size=2,strides=(1,1)) 

#利用@tf.function,将操作转化为graph。 
@tf.function 
def CNN_fn(image): 
	return CNN_cell(image) 

image=tf.zeros([100,200.200,3]) 

#比较两者的执行时间 
CNN_cel1(image) 
CNN_fn(image) 
#调用timeit.timeit,测量代码执行10次的时间 
print("eagerexecution模式下做一层CNN卷积层运算的时间:",timeit.timeit(lambda:CNN_cell(image),number=10)) 
print("graph模式下做一层CNN卷积层运算的时间:",timeit.timeit(lambda:CNN_fn(image),number=10)) 

t32’)
simple_nn_layer(w,x,b)


通过输出结果可知,无法直接查看函数内部b的数值,而返回值可以通过.numpy()查看



通过执行一层cnn计算(相同操作),比较graph和eager execution模式的性能

```python
#timeit测量小段代码的执行时间 
import timeit 
井创建一个卷积层。  
CNN_cell =tf.keras.layers.Conv2D(filters=100,kernel_size=2,strides=(1,1)) 

#利用@tf.function,将操作转化为graph。 
@tf.function 
def CNN_fn(image): 
	return CNN_cell(image) 

image=tf.zeros([100,200.200,3]) 

#比较两者的执行时间 
CNN_cel1(image) 
CNN_fn(image) 
#调用timeit.timeit,测量代码执行10次的时间 
print("eagerexecution模式下做一层CNN卷积层运算的时间:",timeit.timeit(lambda:CNN_cell(image),number=10)) 
print("graph模式下做一层CNN卷积层运算的时间:",timeit.timeit(lambda:CNN_fn(image),number=10)) 

通过比较,我们可以发现graph模式下代码执行效率要高出许多。因此我们以后可以多尝试用@tf.function功能,提高代码运行效率


日常学习总结

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/685586.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

vue3使用codemirror-editor-vue3代码编辑器以及解决格式不对齐 整体左偏问题

一、使用 1.安装 npm install codemirror-editor-vue3 codemirror5.x -S npm install types/codemirror -D 2.使用 import Codemirror from codemirror-editor-vue3; import { formDesign } from //stores/formDesign; import codemirror/mode/javascript/javascript.js;…

LLama2源码分析——Rotary Position Embedding分析

参考&#xff1a;一文看懂 LLaMA 中的旋转式位置编码&#xff08;Rotary Position Embedding&#xff09; 原理推导参考自上文&#xff0c;以下结合huggingface代码分析公式计算过程 1 旋转角度计算 计算公式如下&#xff0c;其中d为词嵌入维度&#xff0c;这部分和论文原文…

微信小程序下载、安装教程-2024年6月6日

微信小程序下载、安装教程-2024年6月6日 一、下载二、安装 一、下载 链接&#xff1a;https://pan.baidu.com/s/1pThpJEtOik9sgOI0F3mr_Q?pwdi1p3 提取码&#xff1a;i1p3 –来自百度网盘超级会员V6的分享 本文是用的网盘下载&#xff0c;具体都差不多。 或者从微信小程序官…

数据分析第一天(pandas简单的对快餐店数据进行操作获得想要的信息,使用apply,groupby)

前言 数据保存在 https://github.com/harkbox/DataAnalyseStudy 数据名称&#xff1a;快餐数据.tsv &#xff08;tsv是用\t作为字符分隔符的文件格式&#xff1b;csv是逗号&#xff09; 因此可以用pandas的read_csv函数读取数据 1.读取数据 import pandas as pd import matp…

Vue3学习记录(第一天)

Vue3学习记录_第一天 背景说明记录Vue3实现响应式前端的反射前端对象的属性赋值Vue3响应式实现过程稿前端移除对象的属性 背景 本次学习主要是看视频学习, 没有跟练, 但是很多知识点感觉又容易忘记. 所以通过笔记的方式输出一下. 说明 估计只能自己看懂, 如果能提供一些其他…

【Python报错】已解决ModuleNotFoundError: No Module Named ‘openyxl’

成功解决“ModuleNotFoundError: No Module Named ‘openyxl’”错误的全面指南 在Python编程中&#xff0c;遇到ModuleNotFoundError: No Module Named openyxl这样的错误通常意味着Python解释器无法找到名为openyxl的模块。然而&#xff0c;这里存在一个常见的拼写错误&#…

解决CSDN 导入Markdown图片失效不显示问题

每次将MarkDown文件导入CSDN的时候&#xff0c;有些图片总是由于防盗链的问题导致图片加载不出来&#xff0c;还得手动再导一遍&#xff0c;极其不方便。所以我们能不能建立一个属于自己的图片服务器或者说在线图库呢&#xff0c;而且每次使用Typora插入图片的时候都会自动的上…

Docker自定义镜像实现(SpringBoot程序为例)

✅作者简介&#xff1a;大家好&#xff0c;我是 Meteors., 向往着更加简洁高效的代码写法与编程方式&#xff0c;持续分享Java技术内容。&#x1f34e;个人主页&#xff1a;Meteors.的博客&#x1f49e;当前专栏&#xff1a;知识备份✨特色专栏&#xff1a;知识分享&#x1f96…

华为HCIP-DATACOM 831最新题目

如图所示的网络&#xff0c;相邻的路由器之间使用直连接口建立EBGP邻居关系&#xff0c;AS号为6500x&#xff0c;其中X为路由器的编号。R1和R4均有到达192.168.1.0/24的静态路由&#xff0c;通过import方式引入BGP。在R3上配置EBGP负载分担的最大等价路由条数为8。缺省情况下&a…

搜索与图论:图中点的层次

搜索与图论&#xff1a;图中点的层次 题目描述参考代码 题目描述 输入样例 4 5 1 2 2 3 3 4 1 3 1 4输出样例 1参考代码 #include <cstring> #include <iostream> #include <algorithm>using namespace std;const int N 100010;int n, m; int h[N], e[N]…

VS2019 QT无法打开 源 文件 “QTcpSocket“

VS2019 QT无法打开 源 文件 "QTcpSocket" QT5.15.2_msvc2019_64 严重性 代码 说明 项目 文件 行 禁止显示状态 错误(活动) E1696 无法打开 源 文件 "QTcpSocket" auto_pack_line_demo D:\vs_qt_project\auto_pack_line_de…

UE5刷植物悬空了

UE5系列文章目录 文章目录 UE5系列文章目录前言一、解决办法 前言 在Unreal Engine5.3中使用植物模式刷各种植物时&#xff0c;有时会发现有的植物要么悬空&#xff0c;要不有刷不上地板的情况。而且悬空的植物还不能接触到地面&#xff0c;感觉很奇怪&#xff0c;就像下图所示…

2024.6.9周报

目录 摘要 ABSTRACT 一、文献阅读 1、相关信息 2、摘要 3、文献解读 1、Introduction 2、文章主要贡献 3、模型架构 4、实验 4、结论 二、代码实现 总结 摘要 本周我阅读了一篇题目为《Unlocking the Potential of Transformers in Time Series Forecasting with …

三十四篇:办公效率革命:深入探索办公自动化系统的全面策略

办公效率革命&#xff1a;深入探索办公自动化系统的全面策略 1. 引言 1.1 办公自动化系统&#xff08;OAS&#xff09;的定义与关键作用 在当前的企业环境中&#xff0c;办公自动化系统&#xff08;Office Automation System, OAS&#xff09;已成为提高效率和执行力的关键技…

全面守护你的健康ZL-0891A小动物多参数监护仪

简单介绍&#xff1a; 12.1英寸彩色TFT显示&#xff0c;分辨率800X600,采用数字血氧DSP算法&#xff0c;低灌注&#xff0c;小动物多参数监护仪具有优良的抗运动性能;动物用血压算法&#xff0c;支持测量各种动物类型,特有的中英文语音报警;支持USB数据导出&#xff0c;可以在…

嵌入式学习记录6.6(拷贝构造/友元函数/常成员函数)

一.拷贝构造函数和拷贝赋值函数 1.1拷贝构造函数功能,格式 拷贝构造函数是一种特殊的构造函数&#xff0c;用来将一个类对象给另一个类对象初始化使用的。 1> 用一个类对象给另一个类对象初始化时&#xff0c;会自动调用拷贝构造函数。 2> 当一个类对作为函数的实参&…

jdk快速配置

在系统变量新建两个变量先下载&#xff0c;直接安装 jdk-****-windows-x64 名称&#xff0c;看看面对java安装目录&#xff0c;我这里是默认目录为例 1.JAVA_HOME C:\Program Files\Java\jdk-1.82.CLASSPATH .;%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jarpath里新建这两个…

韩顺平0基础学java——第18天

p374-395 类变量和类方法 类变量&#xff08;静态变量&#xff09; 例&#xff1a; class Child{ public static Int count&#xff1b;//这个count可以被所有Child实例共享 /..../ } 内存中&#xff0c;static在堆中是独立存放的&#xff0c;并不在某个对象的空间中。 由于…

【数据结构】C语言实现二叉树的基本操作——二叉树的遍历(先序遍历、中序遍历、后序遍历)

C语言实现二叉树的基本操作 导读一、二叉树的遍历二、先序遍历三、中序遍历四、后序遍历五、结点序列六、递归算法与非递归算法的转化结语 导读 大家好&#xff0c;很高兴又和大家见面啦&#xff01;&#xff01;&#xff01; 通过前面的介绍&#xff0c;我们已经认识了二叉树…

SAP 限制物料类型在BOM组件中简介

我们在创建BOM的时候通常是基于成品或者是半成品虚拟件创建BOM。正常情况下某些特殊的物料类型是不存在BOM中的。我们可以通过系统后台配置的方式对物料类型进行控制,控制对应的物料类型是否允许出现在BOM的组件中 1、后台配置路径: SPRO—生产—基本信息—物料清单—项目数…