redis学习笔记(八)—— C++ 操作 Redis

redis学习笔记(八)—— C++ 操作 Redis

redis-plus-plus 库

C++ 操作 Redis 的库有很多,这里使用 redis-plus-plus 库

Github 地址: https://github.com/sewenew/redis-plus-plus

安装 hiredis

redis-plus-plus 是基于 hiredis 实现的(hiredis 是一个 C语言实现的 redis 客户端)

aptinstall libhiredis-dev # Ubuntu yum install hiredis-devel.x86_64 # Centos

下载 redis-plus-plus 源码

git clone https://github.com/sewenew/redis-plus-plus.git 

编译安装 redis-plus-plus

Ubuntu

cd redis-plus-plus # 进入redis-plus-plus 目录make bulid cd bulid cmake ..makemakeinstall

这里使用 cmake 编译,安装 cmake

sudoaptinstall cmake 

构建完成后,在 /usr/local/include/ 中会存在 sw 目录,内部包含 redis-plus-plus 的一些列头文件;

在 /usr/local/lib/ 中存在一系列 libredis 库文件

在这里插入图片描述

使用 redis-plus-plus 库

在使用 g++ 编译或者编写 makefile 时,要使用redis-plus-plus 库,g++就要带上库文件的路径(redis-plus-plus、hiredis)

test:test.cc g++ -o $@ $^ /usr/local/lib/libredis++.a /usr/lib/x86_64-linux-gnu/libhiredis.a 

测试:ping命令

使用redis-plus-plus操作 redis 数据库:创建 sw::redis::Redis 对象,调用成员函数

以 ping 命令为例,测试 redis服务器的连通性

#include<iostream>#include<string>#include<sw/redis++/redis++.h>intmain(){ sw::redis::Redis redis("tcp://127.0.0.1:6379");// 创建 Redis 对象 std::string result = redis.ping(); std::cout << result << std::endl;return0;}
在这里插入图片描述

Redis 构造函数:参数是一个字符串,表示 url(协议名://IP地址:端口号)

redis 客户端与服务器端,通信使用的是 tcp协议,默认端口号为 6379(配置文件中可修改)
redis-plus-plus 库使用起来还是非常简单的,创建sw::redis::Redis,调用其成员函数即可。

通用命令

set

boolset(const StringView &key,const StringView &val,bool keepttl, UpdateType type = UpdateType::ALWAYS);boolset(const StringView &key,const StringView &val,const std::chrono::milliseconds &ttl = std::chrono::milliseconds(0), UpdateType type = UpdateType::ALWAYS);
参数key-val :要设置的 key-val 键值对keepttl : 在更新一个已存在的 key 的值时,对于原本设置的过期时间,是否保留type : 表示更新策略,ALWAYS(总是更新)、IF_EXISTS(键存在时更新,相当于 XX 选项)、IF_NOT_EXISTS(剪枝不存在时更新,相当于 NX 选项)、 NEVER(从不更新)ttl : 在设置 k-v 键值对时,设置过期时间

StringView : 只读字符串

get

sw::redis::OptionalString sw::redis::Redis::get(const sw::redis::StringView &key);

参数 :要获取的 key

返回值:sw::redis::OptionalString

在 redis 中执行 get 命令,当key不存在时,返回 nil

这里 redis-plus-plus 进行了封装,当结果为 nil 时,就无法从 OptionalString 中获取值(通过调用成员方法 value,获取其中的字符串);

OptionalString 还重载了 operator bool,可以向bool值那样被使用(当结果为 nil 时,OptionalString就为false

exists

longlongexists(const sw::redis::StringView &key);longlongexists<T>(std::initializer_list<T> il);// 初始化列表longlongexists<Input>(Input first, Input last);// 迭代器区间

参数

exists 可以删除一个 key,同时也可以删除多个 key;

在传递参数 时,可以只传递一个 key,也可以使用**初始化列表****,还可以使用一段 迭代器区间

返回值 : 存在的key 的个数

del

longlongdel(const sw::redis::StringView &key);longlongdel<T>(std::initializer_list<T> il);longlongdel<Input>(Input first, Input last);

参数:和 exists 一样,可以传递一个 key,初始化列表,迭代器区间

返回值:删除的key 的个数

使用实例

voidtest1(Redis &redis){ redis.flushall();// 清空redis数据 redis.set("key1","111"); redis.set("key2","222"); redis.set("key3","333"); std::string key1 ="key1";auto result1 = redis.get(key1);if(result1) cout <<"get "<< key1 <<" - "<< result1.value()<< endl;else cout << key1 <<" 不存在"<< endl; std::string key2 ="key4";auto result2 = redis.get(key2);if(result2) cout <<"get "<< key2 <<" - "<< result2.value()<< endl;else cout << key2 <<" 不存在"<< endl;auto exist1 = redis.exists("key2"); cout <<"exists1 : "<< exist1 << endl;auto exist2 = redis.exists({"key1","key2","key3","key4","key5"}); cout <<"exists2 : "<< exist2 << endl; std::vector<std::string> keys ={"key1","key2","key3","key4","key5"};auto exist3 = redis.exists(keys.begin(), keys.end()); cout <<"exists3 : "<< exist3 << endl;}
在这里插入图片描述

expire

boolexpire(const sw::redis::StringView &key,const std::chrono::seconds &timeout);boolexpire(const sw::redis::StringView &key,longlong timeout);

参数: 给一个 key 设置过期时间,可以直接传递一个整数(单位:秒);也可以使用 C++ 标准库中的时间间隔类型

返回值:表示是否设置成功

ttl

longlongttl(const sw::redis::StringView &key)

返回值:返回对应 key 的剩余过期时间

keys

voidkeys<Output>(const sw::redis::StringView &pattern, Output output)

参数

pattern :通配表达式,*表示匹配任意多个字符、?表示匹配任意一个字符 …

output : 插入迭代器,keys 获取的结果都插入到指定位置
在这里插入图片描述

在使用的过程中,通过辅助函数构造迭代器即可。(std::back_inserter、std::font_inserter、std::insert_iterator)

type

std::string sw::redis::Redis::type(const sw::redis::StringView &key)

获取 key 对应 value 的数据类型

使用实例

voidtest2(Redis &redis){ redis.flushall(); redis.set("key1","111"); redis.set("key2","222"); redis.set("key3","333");// redis.expire("key1",3); redis.expire("key1", std::chrono::seconds(3));auto ttl1 = redis.ttl("key1"); cout << ttl1 << endl; std::vector<std::string> out; redis.keys("*", std::back_inserter(out));for(auto&e : out) cout << e << endl;auto type = redis.type("key1"); cout << type << endl;}
在这里插入图片描述

string 相关操作

set/get

boolset(const StringView &key,const StringView &val,bool keepttl, UpdateType type = UpdateType::ALWAYS);boolset(const StringView &key,const StringView &val,const std::chrono::milliseconds &ttl = std::chrono::milliseconds(0), UpdateType type = UpdateType::ALWAYS); sw::redis::OptionalString sw::redis::Redis::get(const sw::redis::StringView &key);

mset/mget

voidmset<T>(std::initializer_list<T> il)voidmset<Input>(Input first, Input last)

mset 支持一次设置多个 key-value 键值对;

参数:可以是一个初始化列表(每一个元素都是一个 std::pair 类型),也可以是一段迭代器区间。

voidmget<T, Output>(std::initializer_list<T> il, Output output);voidmget<Input, Output>(Input first, Input last, Output output);

mget 获取多个 key 对应的 value 值;

参数

  • key : 初始化列表,或者一段迭代器区间
  • output : 插入迭代器,mget 获取的结果都插入到指定位置
voidtest1(Redis &redis){ redis.flushall();// redis.mset({std::make_pair("k1", "v1"), std::make_pair("k2", "v2"), std::make_pair("k3", "v3")}); std::vector<std::pair<std::string,std::string>> vct ={std::make_pair("k1","v1"), std::make_pair("k2","v2"), std::make_pair("k3","v3")}; redis.mset(vct.begin(),vct.end()); std::vector<sw::redis::OptionalString> result; redis.mget({"k1","k2","k3","k4"},std::back_inserter(result));for(auto& e : result){if(e) cout << e.value()<< endl;else cout <<"nil"<< endl;}}
在这里插入图片描述
mget 的返回值中可能存在 nil,这里使用 sw::redis::OptionalString 来存储结果

getrange/setrange

std::string getrange(const sw::redis::StringView &key,longlong start,longlong end);longlongsetrange(const sw::redis::StringView &key,longlong offset,const sw::redis::StringView &val);

getrange 获得 key 对应 value(string类型)字符串中,区间[start, end]的子串

setrange 设置(替换) key 对应 value 字符串中,offset 位置后的子串(长度根据 val 长度而定)

incr/decr

voidtest2(Redis &redis){ redis.flushall(); redis.set("key","hello world!!!"); std::string result = redis.getrange("key",5,10); cout << result << endl; redis.setrange("key1",6,"redis"); result = redis.getrange("key1",0,-1); cout << result << endl; redis.set("key2","100"); redis.incr("key2");// +1 redis.incrby("key2",100);// +100auto a = redis.get("key2");if(a) cout << a.value()<< endl;}
在这里插入图片描述
例如 decr/decrby/incrbyfloat 相关的API,这里就不一一展示的,redis-plus-plus 在函数命名上都与命令保持一致,使用起来非常方便。

hash 相关操作

hset/hget/hmset/hmget

hset

longlonghset(const sw::redis::StringView &key,const std::pair<sw::redis::StringView, sw::redis::StringView>&item);longlonghset<T>(const sw::redis::StringView &key, std::initializer_list<T> il);longlonghset(const sw::redis::StringView &key,const sw::redis::StringView &field,const sw::redis::StringView &val); std::enable_if<!std::is_convertible<Input, sw::redis::StringView>::value,longlong>::type hset<Input>(const sw::redis::StringView &key, Input first, Input last);

参数

  • key: sw::redis::StringView 只读字符串
  • val:std::pair 类型的键值对;初始化列表(其中可以是{“filed”,“value”},也可以是一个个的键值对);field、value;还可以是一段初始化列表

返回值:返回设置成功的键值对个数

这里 hset 可以设置多个 field-value 键值对,在初始化列表和迭代器区间中就可以是一个个的std::pair 键值对。

hmset

voidhmset<T>(const sw::redis::StringView &key, std::initializer_list<T> il);voidhmset<Input>(const sw::redis::StringView &key, Input first, Input last);

hget

sw::redis::OptionalString hget(const sw::redis::StringView &key,const sw::redis::StringView &field)

根据 key、field 获取对应的 value 值

返回值:sw::redis::OptionalString 类型(返回值可能为 nil)

hmget

voidhmget<T, Output>(const sw::redis::StringView &key, std::initializer_list<T> il, Output output);voidhmget<Input, Output>(const sw::redis::StringView &key, Input first, Input last, Output output);

hmget,获取多个field 对应的 value值(获取的value值可能为 nil

voidtest(Redis &redis){ redis.flushall();// hset hget redis.hset("key", std::make_pair("f1","v1"));// redis.hset("key",{"f2","v2"}); redis.hset("key",{std::make_pair("f2","v2"), std::make_pair("f3","v3")}); redis.hset("key","f4","v4");auto value = redis.hget("key","f1");if(value) cout << value.value()<< endl;// hmset、hmget// redis.hmset("key", {std::make_pair("aaa", "111"), std::make_pair("bbb", "222"), std::make_pair("ccc", "333")}); std::vector<std::pair<std::string, std::string>> fileds ={std::make_pair("aaa","111"), std::make_pair("bbb","222"), std::make_pair("ccc","333")}; redis.hmset("key", fileds.begin(), fileds.end()); std::vector<sw::redis::OptionalString> result; redis.hmget("key",{"aaa","bbb","ccc","ddd","eee"}, std::back_inserter(result));for(auto&e : result)if(e) cout << e.value()<< endl;}
在这里插入图片描述

hkeys/hvals/hgetall

hkeys:获取 key 对应的 hash 表中,所有的filed

voidhkeys<Output>(const sw::redis::StringView &key, Output output);

hvals:获取 key 对应的 hash 表中所有的 value

voidhvals<Output>(const sw::redis::StringView &key, Output output)

hgetall:获取 key 对应 hash 表中的所有 key-value 键值对

voidhgetall<Output>(const sw::redis::StringView &key, Output output)
voidtest2(Redis &redis){ redis.flushall(); redis.hset("key",{std::make_pair("aaa","111"), std::make_pair("bbb","222"), std::make_pair("ccc","333")}); std::vector<std::string> keys; redis.hkeys("key", std::back_inserter(keys)); cout <<"hkeys : "<< endl;for(auto&e : keys) cout << e << endl; std::vector<std::string> vals; redis.hvals("key", std::back_inserter(vals)); cout <<"hvals : "<< endl;for(auto&e : vals) cout << e << endl; std::vector<std::pair<std::string, std::string>> all; redis.hgetall("key", std::back_inserter(all)); cout <<"hgetall : "<< endl;for(auto&e : all) cout << e.first <<" : "<< e.second << endl;}
在这里插入图片描述

list 相关操作

lpush/lpop/lrpush/rpop

lpush

longlonglpush(const sw::redis::StringView &key,const sw::redis::StringView &val);longlonglpush<T>(const sw::redis::StringView &key, std::initializer_list<T> il);longlonglpush<Input>(const sw::redis::StringView &key, Input first, Input last);

lpush 从 list 左侧插入数据,可以依次插入多个数据。

lpop

sw::redis::OptionalString lpop(const sw::redis::StringView &key);

lpp 从 list 左侧删除一个数据。

rpush/rpop

longlongrpush(const sw::redis::StringView &key,const sw::redis::StringView &val);longlongrpush<T>(const sw::redis::StringView &key, std::initializer_list<T> il);longlongrpush<Input>(const sw::redis::StringView &key, Input first, Input last); sw::redis::OptionalString rpop(const sw::redis::StringView &key);

lrange

voidlrange<Output>(const sw::redis::StringView &key,longlong start,longlong stop, Output output);

获取 list 指定区间的元素。(索引支持负数)

使用实例

voidtest1(Redis &redis){ redis.flushall(); redis.lpush("key",{"111","222","333","444","555"}); redis.lpop("key"); std::vector<std::string> result; redis.lrange("key",0,-1, std::back_inserter(result));for(auto&e : result) cout << e << endl;}
在这里插入图片描述

lindex / llen / linsert / lrem

lindex 根据索引获取 list 中对应元素

sw::redis::OptionalString lindex(const sw::redis::StringView &key,longlong index);

llen 获取 list 的长度(元素个数)

longlongllen(const sw::redis::StringView &key);

linsert:在值 pivot 之前或者之后,插入值 val

longlonglinsert(const sw::redis::StringView &key, sw::redis::InsertPosition position,const sw::redis::StringView &pivot,const sw::redis::StringView &val);

lrem:删除 list 中的元素 val(支持删除多个)

longlonglrem(const sw::redis::StringView &key,longlong count,const sw::redis::StringView &val);
count>0 :从左到右,依次删除 |count| 个元素 val=0 :删除所有的元素 val<0:从右到左,依次删除 |count| 个元素 val

使用实例

voidtest2(Redis &redis){ redis.flushall(); redis.lpush("key",{"111","222","222","333","111"});// 获取索引 2 对应的元素auto index = redis.lindex("key",2);if(index) cout << index.value()<< endl;// 获取 list 中的元素个数int len = redis.llen("key");// 在元素 111 之后插入元素 999 redis.linsert("key", sw::redis::InsertPosition::AFTER,"111","999");// 从左往右,删除一个元素 111 redis.lrem("key",1,"111");// 删除所有的 222 redis.lrem("key",0,"222"); std::vector<std::string> members; redis.lrange("key",0,-1,std::back_inserter(members)); cout <<"list members : ";for(auto& e : members) cout << e <<" "; cout << endl;}
在这里插入图片描述

blpop/brpop

阻塞版本的 lpop/rpop

sw::redis::OptionalStringPair blpop(const sw::redis::StringView &key,const std::chrono::seconds &timeout = std::chrono::seconds{0}); sw::redis::OptionalStringPair blpop(const sw::redis::StringView &key,longlong timeout); sw::redis::OptionalStringPair blpop<T>(std::initializer_list<T> il,const std::chrono::seconds &timeout = std::chrono::seconds{0}); sw::redis::OptionalStringPair blpop<T>(std::initializer_list<T> il,longlong timeout); sw::redis::OptionalStringPair blpop<Input>(Input first, Input last,const std::chrono::seconds &timeout = std::chrono::seconds{0}); sw::redis::OptionalStringPair blpop<Input>(Input first, Input last,longlong timeout);

blpop 可以阻塞等待多个 key,也可以设置 timeout (阻塞时间)

brpop 和 blpop 方法使用一样,只是删除的位置不同。

set 相关操作

sadd

longlong sw::redis::Redis::sadd(const sw::redis::StringView &key,const sw::redis::StringView &member);inlinelonglong sw::redis::Redis::sadd<constchar*>(const sw::redis::StringView &key, std::initializer_list<constchar*> il);longlong sw::redis::Redis::sadd<std::vector<std::string>::iterator>(const sw::redis::StringView &key, std::vector<std::string>::iterator first, std::vector<std::string>::iterator last);

sadd 向 set 中添加一个或者多个元素(member)

smembers

void sw::redis::Redis::smembers<std::back_insert_iterator<std::vector<std::string>>>(const sw::redis::StringView &key, std::back_insert_iterator<std::vector<std::string>> output);

smembers 获取 set 当中的所有元素

spop / srandmember

spop 随机删除 set 中的一个元素并返回

srandmember 随机返回 set 中的一个元素

sw::redis::OptionalString sw::redis::Redis::spop(const sw::redis::StringView &key); sw::redis::OptionalString sw::redis::Redis::srandmember(const sw::redis::StringView &key);

使用实例

voidtest1(Redis &redis){ redis.flushall(); redis.sadd("key","111"); redis.sadd("key",{"111","222","333"}); vector<string> members ={"aaa","bbb","ccc"}; redis.sadd("key", members.begin(), members.end()); vector<string> out; redis.smembers("key", std::back_inserter(out));for(auto&e : out) cout << e << endl;auto randMember = redis.srandmember("key");if(randMember) cout <<"randMenber : "<< randMember.value()<< endl;auto popMember = redis.spop("key");if(popMember) cout <<"spop : "<< popMember.value()<< endl;}
在这里插入图片描述

sinter/sunion/sdiff

对 set 求 交、并、差集

voidsinter<T, Output>(std::initializer_list<T> il, Output output);voidsinter<Input, Output>(Input first, Input last, Output output);voidsunion<T, Output>(std::initializer_list<T> il, Output output);voidsunion<Input, Output>(Input first, Input last, Output output);voidsdiff<T, Output>(std::initializer_list<T> il, Output output);voidsdiff<Input, Output>(Input first, Input last, Output output);

使用实例

voidtest2(Redis &redis){ redis.flushall(); redis.sadd("k1",{"111","222","333"}); redis.sadd("k2",{"222","555","888"}); vector<string> sinter; redis.sinter({"k1","k2"}, std::back_inserter(sinter)); cout <<"sinter : ";for(auto&e : sinter) cout << e <<" "; cout << endl; vector<string> sunion; redis.sunion({"k1","k2"}, std::back_inserter(sunion)); cout <<"sunion : ";for(auto&e : sunion) cout << e <<" "; cout << endl; vector<string> sdiff; redis.sdiff({"k1","k2"}, std::back_inserter(sdiff)); cout <<"sdiff : ";for(auto&e : sdiff) cout << e <<" "; cout << endl;}
在这里插入图片描述
此外例如 sinterstore、sunionstore、sdiffstore,将结果存储到指定 key 中,相比于 sinter/sunion/sdiff 参数多了一个 key(表示结果要存储的 key)

zset 相关操作

zadd

longlongzadd<T>(const sw::redis::StringView &key, std::initializer_list<T> il, sw::redis::UpdateType type = sw::redis::UpdateType::ALWAYS,bool changed =false);longlongzadd(const sw::redis::StringView &key,const sw::redis::StringView &member,double score, sw::redis::UpdateType type = sw::redis::UpdateType::ALWAYS,bool changed =false);longlongzadd<Input>(const sw::redis::StringView &key, Input first, Input last, sw::redis::UpdateType type = sw::redis::UpdateType::ALWAYS,bool changed =false);

zadd 向 zset 中添加元素(member 和 score),可以添加多个元素(初始化列表、迭代器区间)

此外还可以设置更新策略(ALWAYS、IF_EXISTS、IF_NOT_EXISTS、NEVER),这里更新是对于 score 的更新。

zrange

voidzrange<Output>(const sw::redis::StringView &key,longlong start,longlong stop, Output output);

zrange 获取 zset 中指定区间 [start, stop] 的元素;

注意:这里 插入迭代器 output,指向 string 就是获取 member;指向 std::pair<string,string> 类型就是获取 member 和 score。

使用实例

voidtest1(Redis &redis){ redis.flushall(); redis.zadd("key",{std::make_pair("王者荣耀","80"), std::make_pair("穿越火线","95"), std::make_pair("和平精英","90")});// vector<string> out; vector<string> members; redis.zrange("key",0,-1, std::back_inserter(members));for(auto&e : members) cout << e <<" "; cout << endl; vector<std::pair<string, string>> items; redis.zrange("key",0,-1, std::back_inserter(items));for(auto&e : items) cout << e.first <<" : "<< e.second << endl;}
在这里插入图片描述

zcard/zrem/zscore/zrank

zcard 获取 zset 中的元素个数

longlongzcard(const sw::redis::StringView &key);

zrem 根据 member 删除 zset 中元素

longlongzrem(const sw::redis::StringView &key,const sw::redis::StringView &member);
此外,还可以删除 zset 中 score 在指定区间的元素(zremrangebyscore);根据索引删除 zset 中的元素(zremrangebyrank

zscore:获取 zset 中指定 member 对应的 score

sw::redis::OptionalDouble zscore(const sw::redis::StringView &key,const sw::redis::StringView &member);

zrank : 获取 zset 中元素 member 的索引

sw::redis::OptionalLongLong zrank(const sw::redis::StringView &key,const sw::redis::StringView &member);

这里就不一一演示这些方法了,总体使用起来还是比较简单的;详细内容可以参考 redis 官网

本篇文章到这里就结束了,感谢支持
我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=2oul0hvapjsws

Read more

figma + claude + weavy AI :从会用到用好

figma + claude + weavy AI :从会用到用好

Google ai studio + figma + claude.ai + cosmos + Design with Weavy AI 这套头脑风暴工具看完后,你一定可从其中悟出独特、见解,并为之惊讶。我们不需要自己动手去建房子,我们可以借助不同的工具,去找找灵感,为自己创造东西,自然而然的知道自己的感受,和想要的感受。 1 / GoogleAIStudio 端到端 制定原型 GoogleAIStudio非常好,因为它能端到端完成。然后我发现Gemini在界面设计上真的很厉害!(本次以开发一款音乐日记讲述全流程)。 2 / claude.ai 制定品牌指南 (生成品牌指南 guidelines ) 先谈谈设计思想。 就像电影和电视剧有开头、中间、结尾一样,我们现在还不太在意中间和结尾。用户他们不应该觉得我们在抢他们的注意力,或者强迫他们。用户更不愿意看到一堆广告和各种乱七八糟的东西。 很多人,觉得品牌指南听起来很像企业用语,但我认为如claude、gemin这些头脑风暴工具一定能帮助我们找到想要的点。利用claude制定品牌指南,自己想要什么,我们可以看看这个,

By Ne0inhk
【AI 学习】深度解析Transformer核心:注意力机制的原理、实现与应用

【AI 学习】深度解析Transformer核心:注意力机制的原理、实现与应用

文章目录 * 一、引言:注意力机制——Transformer的“灵魂” * 1.1 背景:从RNN到Transformer的范式跃迁 * 1.2 本文核心内容框架 * 二、注意力机制基础:概念与发展历程 * 2.1 注意力机制的核心定义 * 2.2 注意力机制的发展历程 * 2.2.1 早期注意力机制:从机器翻译到图像识别 * 2.2.2 Transformer中的自注意力机制:革命性突破 * 三、Transformer核心:自注意力机制原理深度解析 * 3.1 自注意力机制的核心逻辑 * 3.2 Scaled Dot-Product Attention:自注意力的计算核心 * 3.2.1 步骤1:生成Query、Key、

By Ne0inhk

[人工智能-大模型-71]:模型层技术 - 模型训练六大步:①数据预处理:清洗和整理数据、②数据选择 ③神经网络:预测输出、④损失函数:计算迭代误差、⑤反向传播:计算迭代梯度、⑥ 优化器:更新模型参数

模型训练六大步:①数据预处理:清洗和整理数据、②数据选择 ③神经网络:预测输出、④损失函数:计算迭代误差、⑤反向传播:计算迭代梯度、⑥ 优化器:更新模型参数。 上述是极其清晰、逻辑严密、符合实际工程流程的深度学习训练框架。 它完整覆盖了从原始数据到模型更新的端到端闭环流程,既符合理论原理,又贴近实践。 下面我们对这六大步骤进行系统化、精准化、可操作化的深度解析,并补充每一步的目标、方法、常见技术与关键注意事项,形成一个完整的“训练流水线”认知模型。 🌟 模型训练六大步(完整闭环) ① 数据预处理 → ② 数据选择 → ③ 神经网络预测 → ④ 损失函数计算误差 → ⑤ 反向传播计算梯度 → ⑥ 优化器更新参数 ↓ 回到 ①,进入下一轮迭代 这是一个持续逼近最优函数的动态系统。 ① 数据预处理:清洗和整理数据 → 让数据“可计算” ✅ 目标: * 将原始、杂乱、非结构化的数据,转化为统一、干净、可输入模型的张量格式 ✅ 核心任务:

By Ne0inhk
【保姆级教程】AI图生图+视频生成完整工作流(附提示词+参数表)

【保姆级教程】AI图生图+视频生成完整工作流(附提示词+参数表)

【保姆级教程】AI图生图+视频生成完整工作流(附提示词+参数表) 目录 * 一、前言 * 二、环境搭建与工具选择 * 三、第一步:生成高质量基础图片(图生图) * 3.1 模型选择 * 3.2 提示词编写 * 3.3 参数设置参考 * 四、第二步:图生视频核心操作 * 4.1 AnimateDiff插件安装与配置 * 4.2 运动参数详解 * 4.3 生成视频与后处理 * 五、实战案例与提示词解析 * 六、常见问题与解决方案(避坑指南) * 七、资源下载 * 八、结语 一、前言 最近AI视频生成技术火得一塌糊涂,从Runway Gen-2到Stable Diffusion的AnimateDiff插件,

By Ne0inhk