当前位置: 首页 > article >正文

【TensorFlow】tensorflow简介和环境搭建、入门

在这里插入图片描述
tensorflow中文官网

1. TensorFlow简介和环境搭建

1. TensorFlow简介

1.1 TensorFlow是什么

  • TensorFlow是深度学习领域使用最为广泛的一个Google的开源软件库(最初由Google brain team进行开发的内部库,由于它的易用性Google决定把它开源出来).

  • 采取数据流图,用于数值计算.

    节点——处理数据

    线——节点间的输入输出关系

    数据流图中的数据叫做tensor, 表示张量, 即N维数据, tensor在数据流图中流动表示计算的过程, 这也是tensorflow名字的由来.
    在这里插入图片描述

  • 支持多种平台,GPU、CPU、移动设备

  • tensorflow特性:

    • 高度的灵活性: 只要能把数据的计算表示成数据流图就可以使用tensorflow
    • 真正的可移植性: 比如CPU、GPU、移动设备等等
    • 产品和科研结合
      • tensorflow研究最初是用于科研的,其实科研和工程还有一定的距离,科研的代码需要进一步各种各样的优化才能真正的做到产品上去,但是对于tensorflow则没有这个问题,Google团队把tensorflow优化的已经比较好了,做研究的代码可以无缝的用到产品上
    • 自动求微分
    • 多语言支持
      • tensorflow除了python以外,还支持各种各样的语言,比如说c++、java、javascript、R语言等
    • 性能最优化
      • 在tensorflow刚刚出来的时候由于它运行的比较慢,很多深度学习库呢都会拿tensorflow来进行比较,然后来证明自己比tensorflow好多少倍,但是随着tensorflow一步一步的进行开发,这种情况一去不复返了,tensorflow现在应该是运行最快的一个库,对于分布式的tensorflow来说,它的加速比几乎是线性的

1.2 tensorflow版本变迁

在这里插入图片描述

1.3 tensorflow 2.0 架构

在这里插入图片描述

  • tensorflow2.0主要特性:
    • 使用tf.keras和eager mode(动态图模式)进行更简单的模型构建.
      • 使用tf.data加载数据
      • 使用tf.keras构建模型,也可使用premade estimator来验证模型
        • 使用tensorflow hub进行迁移学习
      • 使用eager mode运行和调试
      • 使用分发策略来进行分布式训练
      • 导出到SavedMode
      • 使用TensorFlow Serve、Tensorflow Lite、Tensorflow.js部署模型
    • 鲁棒的跨平台模型部署
      • TensorFlow服务
        • 直接通过HTTP/RESR或GRPC/协议缓冲区
      • TensorFlow Lite——可部署到Android、iOS和嵌入式系统上
      • TensorFlow.js——在JavaScript中部署
      • 其他语言
        • C、Java、Go、C#、Rust、Julia、R等
    • 强大的研究试验
      • Keras功能API和子类API、允许创建复杂的拓扑结构
      • 自定义训练逻辑、使用tf.GraddientTape和tf.custom_gradient进行更细粒度的控制
      • 底层API自始至终可以与高层结合使用、完全的可定制
      • 高级扩展:Ragged Tensor、Tensor2Tensor等
    • 清除不推荐使用的API和减少重复来简化API

1.4 tensorflow vs pytorch

  • 入门难易

    • Tensorflow1.*
      • 静态图(无eager mode)

      • 学习额外概念

      • 如图、会话、变量、占位符等

        # Tensorflow1.0实现
        import tensorflow as tf
        
        # 构建计算图
        x = tf.Variable(0.)
        y = tf.Variable(1.)
        add_op = x.assign(x + y)  # x = x + y
        div_op = y.assign(y / 2)  # y = y / 2
        
        # TensorFlow1.0中必须先打开会话,才能计算数据流图
        with tf.Session() as sess:
        	sess.run(tf.global_variables_initializer())  # 初始化会话
        	for iteration in range(50):
        		sess.run(add_op)
        		sess.run(div_op)
        	print(x.eval())  # 也可用sess.eval(x)
        
    • Tensorflow2.0
      • 动态图(eager mode默认打开)

      • Eager mode避免1.0缺点,直接集成在Python中

        import tensorflow as tf
        
        x = tf.constant(0.)
        y = tf.constant(1.)
        for iteration in range(50):
        	x = x + y
        	y = y / 2
        print(x.numpy())
        
    • Pytorch
      • 动态图

      • Numpy的扩展,直接集成在Python中

        import torch
        
        x = torch.Tensor([0.])
        y = torch.Tensor([1.])
        for iteration in range(50):
        	x = x + y
        	y = y / 2
        print(x)
        
  • 图创建和调试

    • TensorFlow 1.* : 静态图, 难易调试, 需要学习tfdbg工具
    • TensorFlow 2.0和pytorch: 动态图, python自带调试工具即可调试
  • 全面性

    • pytorch缺少
      • 沿维度反转张量
      • 检查无穷与非数值张量
      • 快速傅里叶变换
    • 随着时间的变化, 越来越接近
  • 序列化与部署

    • tensorflow2.0的序列化支持非常广泛
      • 图保存为protocol buffer格式
      • 跨语言
      • 跨平台
    • pytorch支持较为简单

2. 环境搭建

2.1 本地虚拟环境安装tensorflow

  • 安装cpu版本tensorflow

    • 直接使用pip install tensorflow安装即可
  • 安装gpu版本tensorflow

    • 确认显卡型号,查看是否支持cuda运算, 确认驱动版本(cuda11.x以上要求450.x以上的驱动版本) 找到对应的cuda版本, 下载安装.

      在这里插入图片描述

    • 安装CUPTI工具, cuda11.3已经自带这个工具.所以可以不用安装.

    • 安装cuDNN,访问 https://developer.nvidia.com/rdp/cudnn-archive, 找到需要安装的cuDNN版本,可以通过右键另存为下载cuDNN.

    • 把cuDNN解压到CUDA的安装目录,一般是: C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.3

    • 配置环境变量.在系统的PATH环境变量中,新增以下几个环境变量:

      C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.3\bin
      C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.3\extras\CUPTI\lib64
      C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.3\include
      
    • 重启jupyter环境, 导入tensorflow,执行print("Num GPUs Available: ", len(tf.config.list_physical_devices('GPU'))) 查看是否有可用的GPU. 如果显示正常, 那么配置OK.

    • 后续写tensorflow的代码,会自动使用GPU去执行, 不需要对代码做任何修改.

2.2 google colab使用tensorflow

  • google colab提供了可直接使用的tensorflow环境, 而且可以方便切换版本.
  • 登录google账号, 搜索google colab进入google colab页面, 点击文件新建笔记本

在这里插入图片描述

  • 在打开的笔记本中,如果想使用tensorflow2.0环境执行%tensorflow_version 2.x 那么当前笔记本使用的tensorflow即为2.0以上的版本.

2. TensorFlow入门

1. 基础API使用

TensorFlow中定义的数据叫做Tensor(张量), Tensor又分为常量和变量.

1.1 常量的定义和使用

常量一旦定义值不能改变.

使用tf.constant定义常量

t = tf.constant([[1., 2., 3.], [4., 5., 6.]])

# 可以像numpy的ndarray一样使用tensor
print(t)
print(t[:, 1:])
print(t[..., 1]) # 或t[:, 1]

输出:

tf.Tensor(
[[1. 2. 3.]
 [4. 5. 6.]], shape=(2, 3), dtype=float32)
tf.Tensor(
[[2. 3.]
 [5. 6.]], shape=(2, 2), dtype=float32)
tf.Tensor([2. 5.], shape=(2,), dtype=float32)

常量的操作:

print(t+10) # 每个元素都加10
print(tf.square(t)) # 每个元素都做平方
print(t @ tf.transpose(t)) # @表示矩阵的点乘

输出:

tf.Tensor(
[[11. 12. 13.]
 [14. 15. 16.]], shape=(2, 3), dtype=float32)
tf.Tensor(
[[ 1.  4.  9.]
 [16. 25. 36.]], shape=(2, 3), dtype=float32)
tf.Tensor(
[[14. 32.]
 [32. 77.]], shape=(2, 2), dtype=float32)

常量tensor和numpy中的ndarray的转化:

# .numpy()可以把tensor转化为ndarray
print(t.numpy())
print(np.square(t)) 
np_t = np.array([[1., 2., 3.], [4., 5., 6.]])
# 直接使用ndarray生成一个tensor
print(tf.constant(np_t))

输出:

[[1. 2. 3.]
 [4. 5. 6.]]
[[ 1.  4.  9.]
 [16. 25. 36.]]
tf.Tensor(
[[1. 2. 3.]
 [4. 5. 6.]], shape=(2, 3), dtype=float64)

生成标量:

# scalar
t = tf.constant(2.718)
print(t.numpy())
print(t.shape)

输出:

2.718
()

使用字符串

# strings
t = tf.constant("cafe")
print(t)
print(tf.strings.length(t)) # 获取字符串的长度
print(tf.strings.length(t, unit="UTF8_CHAR")) # 获取utf8编码的长度
print(tf.strings.unicode_decode(t, "UTF8")) # 把字符串转化为utf8编码

输出:

tf.Tensor(b'cafe', shape=(), dtype=string)
tf.Tensor(4, shape=(), dtype=int32)
tf.Tensor(4, shape=(), dtype=int32)
tf.Tensor([ 99  97 102 101], shape=(4,), dtype=int32)

使用字符串数组

# string array
t = tf.constant(["cafe", "coffee", "咖啡"])
print(tf.strings.length(t, unit="UTF8_CHAR"))
r = tf.strings.unicode_decode(t, "UTF8")
print(r)

输出:

tf.Tensor([4 6 2], shape=(3,), dtype=int32)
<tf.RaggedTensor [[99, 97, 102, 101], [99, 111, 102, 102, 101, 101], [21654, 21857]]>

ragged tensor 不整齐的tensor, 上面的tensor每个字符串长度不一致.

创建ragged tensor

r = tf.ragged.constant([[11, 12], [21, 22, 23], [], [41]])
# index op
print(r)
print(r[1])
# 左闭右开
print(r[1:2])

输出:

<tf.RaggedTensor [[11, 12], [21, 22, 23], [], [41]]>
tf.Tensor([21 22 23], shape=(3,), dtype=int32)
<tf.RaggedTensor [[21, 22, 23]]>

ragged tensor的操作:

r2 = tf.ragged.constant([[51, 52], [], [71]])
# 拼接操作, axis=0按行拼接. 如果按列拼接会报错. 因为行数不一致.
print(tf.concat([r, r2], axis = 0))

输出:

<tf.RaggedTensor [[11, 12], [21, 22, 23], [], [41], [51, 52], [], [71]]>

按列拼接:

r3 = tf.ragged.constant([[13, 14], [15], [], [42, 43]])
print(tf.concat([r, r3], axis = 1))

输出:

<tf.RaggedTensor [[11, 12, 13, 14], [21, 22, 23, 15], [], [41, 42, 43]]>

把ragged tensor转化为普通tensor

# 缺元素的地方会补0, 0在正常元素的后面.
print(r.to_tensor())

输出:

tf.Tensor(
[[11 12  0]
 [21 22 23]
 [ 0  0  0]
 [41  0  0]], shape=(4, 3), dtype=int32)

sparse tensor 稀疏tensor, tensor中大部分元素是0, 少部分元素是非0.

创建sparse tensor

# indices指示正常值的索引, 即哪些索引位置上是正常值. 
# values表示这些正常值是多少.
# indices和values是一一对应的. [0, 1]表示第0行第1列的值是1, [1,0]表示第一行第0列的值是2, [2, 3]表示第2行第3列的值是3, 以此类推.
# dense_shape表示这个SparseTensor的shape是多少
s = tf.SparseTensor(indices = [[0, 1], [1, 0], [2, 3]],
                    values = [1., 2., 3.],
                    dense_shape = [3, 4])
print(s)
# 把sparse tensor转化为稠密矩阵 
print(tf.sparse.to_dense(s))

输出:

SparseTensor(indices=tf.Tensor(
[[0 1]
 [1 0]
 [2 3]], shape=(3, 2), dtype=int64), values=tf.Tensor([1. 2. 3.], shape=(3,), dtype=float32), dense_shape=tf.Tensor([3 4], shape=(2,), dtype=int64))
tf.Tensor(
[[0. 1. 0. 0.]
 [2. 0. 0. 0.]
 [0. 0. 0. 3.]], shape=(3, 4), dtype=float32)

sparse tensor的运算:

# 乘法
s2 = s * 2.0
print(s2)

try:
    # 加法不支持.
    s3 = s + 1
except TypeError as ex:
    print(ex)

s4 = tf.constant([[10., 20.],
                  [30., 40.],
                  [50., 60.],
                  [70., 80.]])
# 得到一个3 * 2 的矩阵
print(tf.sparse.sparse_dense_matmul(s, s4))

输出:

SparseTensor(indices=tf.Tensor(
[[0 1]
 [1 0]
 [2 3]], shape=(3, 2), dtype=int64), values=tf.Tensor([2. 4. 6.], shape=(3,), dtype=float32), dense_shape=tf.Tensor([3 4], shape=(2,), dtype=int64))
unsupported operand type(s) for +: 'SparseTensor' and 'int'
tf.Tensor(
[[ 30.  40.]
 [ 20.  40.]
 [210. 240.]], shape=(3, 2), dtype=float32)

注意在定义sparse tensor的时候 indices必须是排好序的. 如果不是,定义的时候不会报错, 但是在to_dense的时候会报错:

# [0, 2]在[0, 1]前面
s5 = tf.SparseTensor(indices = [[0, 2], [0, 1], [2, 3]],
                    values = [1., 2., 3.],
                    dense_shape = [3, 4])
print(s5)
# 可以通过reorder对排序, 这样to_dense就没问题了.
s6 = tf.sparse.reorder(s5)
print(tf.sparse.to_dense(s6))

输出:

SparseTensor(indices=tf.Tensor(
[[0 2]
 [0 1]
 [2 3]], shape=(3, 2), dtype=int64), values=tf.Tensor([1. 2. 3.], shape=(3,), dtype=float32), dense_shape=tf.Tensor([3 4], shape=(2,), dtype=int64))
tf.Tensor(
[[0. 2. 1. 0.]
 [0. 0. 0. 0.]
 [0. 0. 0. 3.]], shape=(3, 4), dtype=float32)

1.2 变量

变量和常量相对, 变量定义之后可以改变值.

变量通过tf.Variable来定义.

v = tf.Variable([[1., 2., 3.], [4., 5., 6.]])
# 打印的是Variable对象
print(v)
# 打印的是变量的值的tensor
print(v.value())
# 打印的是ndarray
print(v.numpy())

输出:

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

对变量进行赋值:

# 对变量之间赋值, 所有位置乘于2
v.assign(2*v)
print(v.numpy())
# 对变量的某个位置进行赋值
v[0, 1].assign(42)
print(v.numpy())
# 对变量的某一行赋值
v[1].assign([7., 8., 9.])
print(v.numpy())

输出:

[[ 2.  4.  6.]
 [ 8. 10. 12.]]
[[ 2. 42.  6.]
 [ 8. 10. 12.]]
[[ 2. 42.  6.]
 [ 7.  8.  9.]]

注意: 变量赋值必须使用assign, 不能直接用=.

try:
    v[1] = [7., 8., 9.]
except TypeError as ex:
    print(ex)

打印:

'ResourceVariable' object does not support item assignment

1. 3 TensorFlow的数学运算

在TensorFlow中既可以使用数学运算符号进行数学运算也可以使用TensorFlow定义好的数学运算方法.

#  定义常量
a = tf.constant(2)
b = tf.constant(3)
c = tf.constant(5)

# 定义运算, 也可以直接使用python运算符+,-, * / ...
add = tf.add(a, b)
sub = tf.subtract(a, b)
mul = tf.multiply(a, b)
div = tf.divide(a, b)

# 打印运算结果
print("add =", add.numpy())
print("sub =", sub.numpy())
print("mul =", mul.numpy())
print("div =", div.numpy())

输出:

add = 5
sub = -1
mul = 6
div = 0.6666666666666666

聚合运算:

x = np.random.randint(0,10, size=(3,6))
x_mean = tf.reduce_mean(x)
# 默认会聚合所有的维度
print(x_mean.numpy())

# 可以指定聚合的轴
x_reduce_mean = tf.reduce_mean(x, axis=0)
print(x_reduce_mean.numpy())

输出:

5
[5 6 6 5 6 1]

矩阵运算:

# 矩阵运算
x = np.random.randint(0,10, size=(3,6))
y = np.random.randint(0,10, size=(6,4))
dot = tf.matmul(x, y)
print(dot.numpy())

输出:

[[ 67  68 112  27]
 [105 141 191  67]
 [ 68 121 135  89]]

2. 使用tensorflow实现线性回归

实现一个算法主要从以下三步入手:

  1. 找到这个算法的预测函数, 比如线性回归的预测函数形式为:y = wx + b,
  2. 找到这个算法的损失函数 , 比如线性回归算法的损失函数为最小二乘法
  3. 找到让损失函数求得最小值的时候的系数, 这时一般使用梯度下降法.

使用TensorFlow实现算法的基本套路:

  1. 使用TensorFlow中的变量将算法的预测函数, 损失函数定义出来.

  2. 使用梯度下降法优化器求损失函数最小时的系数

  3. 分批将样本数据投喂给优化器,找到最佳系数

    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    %matplotlib inline
    import tensorflow as tf
    
    # 生成线性数据
    x = np.linspace(0, 10, 20) + np.random.randn(20)
    y = np.linspace(0, 10, 20) + np.random.randn(20)
    
    # W, B 定义为变量
    W = tf.Variable(initial_value=np.random.randn())
    B = tf.Variable(initial_value=np.random.randn())
    
    # 定义线性模型, TensorFlow2.x没有占位符了.把线性模型封装为一个函数, x作为参数传入
    def linear_regression(x):
        return W * x + B
    
    # 定义损失函数
    def mean_square_loss(y_pred, y_true):
        return tf.reduce_sum(tf.square(y_pred - y_true)) / 20
    
    # 优化器 随机梯度下降法
    optimizer = tf.optimizers.SGD(0.01)
    
    # 定义优化过程
    def run_optimization():
        # 把计算过程放在梯度带中执行,可以实现自动微分
        with tf.GradientTape() as g:
            pred = linear_regression(x)
            loss = mean_square_loss(pred, y)
        # 计算梯度
        gradients = g.gradient(loss, [W, B])
        
        # 更新W和B
        optimizer.apply_gradients(zip(gradients, [W, B]))
    
        # 训练
    for step in range(1, 5001):
        # 每次训练都要更新W和B
        run_optimization()
        # 展示结果
        if step % 100 == 0:
            pred = linear_regression(x)
            loss = mean_square_loss(pred, y)
            print(f'step: {step}, loss: {loss}, W: {W.numpy()}, B: {B.numpy()}')
    

    结果:

     step: 100, loss: 1.6047000885009766, W: 0.928673505783081, B: 0.7533596754074097
    step: 200, loss: 1.5341135263442993, W: 0.9686957001686096, B: 0.4936709403991699
      step: 300, loss: 1.5106890201568604, W: 0.9917512536048889, B: 0.34407249093055725
      step: 400, loss: 1.5029155015945435, W: 1.0050327777862549, B: 0.2578935921192169
      ...
      step: 4600, loss: 1.4990546703338623, W: 1.0230802297592163, B: 0.1407904475927353
      step: 4700, loss: 1.4990546703338623, W: 1.0230802297592163, B: 0.1407904475927353
      step: 4800, loss: 1.4990546703338623, W: 1.0230802297592163, B: 0.1407904475927353
      step: 4900, loss: 1.4990546703338623, W: 1.0230802297592163, B: 0.1407904475927353
      step: 5000, loss: 1.4990546703338623, W: 1.0230802297592163, B: 0.1407904475927353
    

    根据计算出来的系数和截距,画出预测趋势线, 发现能够比较好的拟合样本数据的趋势.

    plt.scatter(x, y)
    x_test = np.linspace(0, 10, 20).reshape(-1, 1)
    plt.plot(x_test, linear.coef_ * x_test + linear.intercept_, c='r')
    
    plt.plot(x_test, W.numpy() * x_test + B.numpy(), c='g', lw=10, alpha=0.5)
    

    在这里插入图片描述

    3. 使用TensorFlow实现逻辑回归

    实现逻辑回归的套路和实现线性回归差不多, 只不过逻辑回归的目标函数和损失函数不一样而已.

    import numpy as np
    import matplotlib.pyplot as plt
    from sklearn.datasets import make_blobs
    import tensorflow as tf
    
    
    data, target = make_blobs(centers=2)
    plt.scatter(data[:, 0], data[:, 1], c=target)
    
    w = tf.Variable(initial_value= np.random.randn(2, 2) * 0.01, dtype=tf.float32)
    b = tf.Variable(initial_value=0, dtype=tf.float32)
    
    x = tf.constant(data, dtype=tf.float32)
    y = tf.constant(target, dtype=tf.int32)
    
    # 对y做one_hot处理
    y  = tf.one_hot(y, depth=2)
    
    # 定义目标函数
    def sigmoid(x):
        return tf.nn.sigmoid(tf.matmul(x, w) + b) # (100, 2) * (2, 2) -> (100, 2)
    
    # 定义损失函数
    def loss(y_true, y_pred):
        # 对y_pred进行截断
        y_pred = tf.clip_by_value(y_pred, 1e-9, 1)
        return tf.reduce_mean(tf.multiply(y_true, tf.math.log(1/y_pred)))
    
    # 定义优化器
    optimizer = tf.optimizers.SGD(0.001)
    
    # 定义优化过程
    def run_optimization():
        with tf.GradientTape() as g:
            pred = softmax(x) # shape(100, 1)
            cost = loss(y, pred)
            
        # 计算梯度
        gradients = g.gradient(cost, [w, b])
        
        # 更新,w, b
        optimizer.apply_gradients(zip(gradients, [w, b]))
        
        
    # 计算准确率
    def accuracy(y_true, y_pred):
        # 根据阈值对y_pred概率转化成具体类别
        # 100, 2
        # 取最大值的索引
        return tf.reduce_mean(tf.cast(tf.equal(tf.argmax(y_true, 1), tf.argmax(y_pred, axis=1)), dtype=tf.float32))
    
    
    # 开始训练
    for i in range(1, 10000):
        run_optimization()
        
        if i % 100 == 0:
            y_pred = softmax(x)
            acc = accuracy(y, y_pred)
            loss_ = loss(y, y_pred)
            print(f'准确率: {acc}, 损失: {loss_}')
    

    输出:

    准确率: 0.9200000166893005, 损失: 0.3144806921482086
    准确率: 0.8999999761581421, 损失: 0.2893371284008026
    准确率: 0.9100000262260437, 损失: 0.26885926723480225
    准确率: 0.9100000262260437, 损失: 0.25160202383995056
    准确率: 0.9200000166893005, 损失: 0.23685793578624725
    准确率: 0.9100000262260437, 损失: 0.22414466738700867
    准确率: 0.9200000166893005, 损失: 0.21309375762939453
    准确率: 0.9200000166893005, 损失: 0.20341530442237854
    准确率: 0.9200000166893005, 损失: 0.19487883150577545
    准确率: 0.9399999976158142, 损失: 0.1872999519109726
    准确率: 0.9399999976158142, 损失: 0.18053019046783447
    准确率: 0.9399999976158142, 损失: 0.17444901168346405
    ...
    准确率: 0.949999988079071, 损失: 0.09776999801397324
    准确率: 0.949999988079071, 损失: 0.0971640795469284
    准确率: 0.949999988079071, 损失: 0.09657695889472961
    准确率: 0.949999988079071, 损失: 0.09600784629583359
    准确率: 0.949999988079071, 损失: 0.09545581787824631
    准确率: 0.949999988079071, 损失: 0.09492019563913345
    准确率: 0.949999988079071, 损失: 0.09440017491579056
    

http://www.kler.cn/a/463236.html

相关文章:

  • Java重要面试名词整理(十八):Sentinel
  • 【C语言】_指针运算
  • OFDM学习-(二)长短序列和PPDU整体数据处理流程
  • Couchbase 和数据湖技术的区别、联系和相关性分析
  • 快速上手LangChain(三)构建检索增强生成(RAG)应用
  • vue2、element的el-select 选项框的宽度设置、文本过长问题
  • 掌握 Stream API - Java 8 的力量
  • 智能工厂的设计软件 应用场景的一个例子:为AI聊天工具添加一个知识系统 之12 方案再探之3:特定于领域的模板 之2 首次尝试和遗留问题解决
  • 异常与中断(上)
  • C++设计模式:状态模式(自动售货机)
  • HIVE函数使用案例之----行列转换
  • nginx学习之路-nginx配置https服务器
  • 17爬虫:关于DrissionPage相关内容的学习01
  • 大模型—Ollama将Python函数作为参数传递,增强函数调用功能
  • shell脚本的【算数运算、分支结构、test表达式】
  • PHP:IntelliJ IDEA 配置 PHP 开发环境及导入PHP项目
  • OpenCV 特征检测和特征匹配方法汇总
  • 如何使用大语言模型进行事件抽取与关系抽取
  • smolagents:一个用于构建代理的简单库
  • SpringBoot教程(三十二) SpringBoot集成Skywalking链路跟踪
  • hhdb客户端介绍(65)
  • HT-HaiBOX边缘计算盒 智慧工厂方案,智慧医疗方案,智慧加油站方案,智慧安防方案,智慧城市方案;方案定制开发
  • Python编程实现“天天酷跑”小游戏(源码附上)
  • 基于单片机的野营自动感应灯系统(论文+源码)
  • 使用Wikitext2数据集对Llama-7B和Llama3-8B模型进行50%权重剪枝的一般步骤和可能的实现方式
  • 大数据技术-Hadoop(三)Mapreduce的介绍与使用