Note that, in an HA cluster, the Standby NameNode also
performs checkpoints of the namespace state, and thus it
is not necessary to run a Secondary NameNode,
CheckpointNode, or BackupNode in an HA cluster. In fact,
to do so would be an error. This also allows one who is
reconfiguring a non-HA-enabled HDFS cluster to be
HA-enabled to reuse the hardware which they had
previously dedicated to the Secondary NameNode.
np_var = np.array([1, 2]) K.is_keras_tensor(np_var) # False keras_var = K.variable(np_var) K.is_keras_tensor(keras_var) # A variable is not a Tensor. # False keras_placeholder = K.placeholder(shape=(2, 4, 5)) K.is_keras_tensor(keras_placeholder) # A placeholder is a Tensor. # True
from keras import backend as K a = K.placeholder((2, 2), sparse=False) print(K.is_sparse(a)) # False b = K.placeholder((2, 2), sparse=True) print(K.is_sparse(b)) # True
from keras import backend as K tf_session = K.get_session() val = np.array([[1, 2], [3, 4]]) kvar = K.variable(value=val) input = keras.backend.placeholder(shape=(2, 4, 5)) K.shape(kvar) # <tf.Tensor 'Shape_8:0' shape=(2,) dtype=int32> K.shape(input) # <tf.Tensor 'Shape_9:0' shape=(3,) dtype=int32> # To get integer shape (Instead, you can use K.int_shape(x)) K.shape(kvar).eval(session=tf_session) # array([2, 2], dtype=int32) K.shape(input).eval(session=tf_session) # array([2, 4, 5], dtype=int32)
int_shape
1
defint_shape(x)
返回张量shape
返回值:tuple(int)/None
1 2 3 4 5 6 7 8
from keras import backend as K input = K.placeholder(shape=(2, 4, 5)) K.int_shape(input) # (2, 4, 5) val = np.array([[1, 2], [3, 4]]) kvar = K.variable(value=val) K.int_shape(kvar) # (2, 2)
ndim
1
defndim(x)
返回张量的阶数
返回值:int
1 2 3 4 5 6 7 8
from keras import backend as K input = K.placeholder(shape=(2, 4, 5)) val = np.array([[1, 2], [3, 4]]) kvar = K.variable(value=val) K.ndim(input) # 3 K.ndim(kvar) # 2
dtype
1
defdtype(x)
返回张量的数据类型
返回值:str
float32
float32_ref
1 2 3 4 5 6 7 8 9 10 11 12 13 14
from keras import backend as K K.dtype(K.placeholder(shape=(2,4,5))) # 'float32' K.dtype(K.placeholder(shape=(2,4,5), dtype='float32')) # 'float32' K.dtype(K.placeholder(shape=(2,4,5), dtype='float64')) # 'float64'__Keras variable__
kvar = K.variable(np.array([[1, 2], [3, 4]])) K.dtype(kvar) # 'float32_ref' kvar = K.variable(np.array([[1, 2], [3, 4]]), dtype='float32') K.dtype(kvar) # 'float32_ref'
eval
1
defeval(x)
求得张量的值
返回值:NDA
1 2 3 4 5
from keras import backend as K kvar = K.variable(np.array([[1, 2], [3, 4]]), dtype='float32') K.eval(kvar) # array([[ 1., 2.], # [ 3., 4.]], dtype=float32)
`zeros
1 2 3 4 5
defzeros( shape, dtype='float32', name=None )
生成shape大小的全0张量
1 2 3 4 5 6
from keras import backend as K kvar = K.zeros((3,4)) K.eval(kvar) # array([[ 0., 0., 0., 0.], # [ 0., 0., 0., 0.], # [ 0., 0., 0., 0.]], dtype=float32)
fnmain(){ let favorite_color: Option<&str> = None; let is_tuesday = false; let age: Result<u8, _> = "34".parse();
ifletSome(color) = favorite_color{ //模式匹配 //注意这里是`=`而不是一般值比较`==` //`while`同 println!("favorite color is {}", color}; }elseif is_tuesday{ //普通`if`条件语句 println!("Tuesday is green day!"); }elseifletOk(age) = age{ //`age`变量覆盖原变量 //此时`age`是`u8`类型 if age > 30 { //因此此条件不能提出,因为两个`age`变量不同, //不能共存在同一条语句中 println!("Using purple as the background color"); }else{ println!("Using orange as the background color"); } }else{ println!("Using blue as the background color"); } }
let p = Point{x: 0, y: 7}; let Point{x: a, y: b} = p; //`Point{x: a, y: b}`是模式”Point结构体“ //解构结构体
let p = Point{x: 0, y: 7}; let Point{x, y} = p; //模式匹配解构结构体简写 //只要列出结构体字段,模式创建相同名称的变量
let p = Point{x: 0, y: 7}; match p { Point {x, y: 0} => println!("on the x axis at {}", x), Point {x: 0, y} => println!("on the y axis at {}", y), Point {x, y} => println!("on neither axis: ({}, {})", x, y), //这里没有`_`通配符,因为`Point {x, y}`模式已经 //是irrefutable,不需要 } }
let msg = Message::Hello { id: 5 }; match msg{ Message::Hello{ id: id_variable @ 3...7 } => { //匹配结构体模式(值绑定`id_variable`)&&值在`3...7`范围 println!("Found an id in range: {}", id_variable) }, Message::Hello{ id: 10...12 } => { //此分支模式指定了值的范围,但是没有绑定值给变量`id` //结构体匹配简略写法不能应用与此 println!("Found an id in another range") } Message::Hello{ id } => { //此分支结构体匹配简略写法,值绑定于`id` println!("Found some other id: {}", id) }, }
fnmain(){ let x = vec![1, 2, 3] let equal_to_x = move |z| z == x; println!("can't use x here: {:?}", x); //此时`x`的所有权已经转移进闭包,不能在闭包外使用 let y = vec![1, 2, 3]; assert!(equal_to_x(y));
use std::thread; use std::time:Duration; fnmain(){ let handle = thread::spawn(|| { //`thread::spawn`接受一个闭包作为参数,返回 //`JoinHandle`类型的值(不是引用) for i in1..10{ println!("number {} from spwaned thread!", i); thread::sleep(Duration::from_millis(1)); } );
for i in1..5{ println!("number{} from main thread!", i); thread::sleep(Duration::from_millis(1)); }
thread::spawn(move || {d let vals = vec![ String::from("move"), String::from("messages"), String::from("for"), String::from("you"), ]; for val in vals{ tx.send(val).unwrap(); thread::sleep(Duration::from_secs(1)); } });
let received = rx.recv().unwrap(); //`recv`将阻塞直到接收到一个值,返回`Result<T, E>` //通道发送端关闭时`recv`将返回`Err<E>`表明不会有新值
let received = rx.try_recv().unwrap(); //`try_recv`不阻塞,立刻返回`Result<T, E>`,`Err<E>` //表示当前没有消息 //可以再循环中多次调用`try_recv`,有消息进行处理, //否则进行其他工作直到下次调用`try_recv`
for received in rx{ //将接收端`rx`当作迭代器使用,返回接收到值 println!("Got: {}", received); } }
for _ in0..10{ let counter = Arc::clone(&counter); let handle = thread::spawn(move || { letmut num = counter.lock().unwrap(); //`lock`返回一个`MutexGuard`类型的智能指针, //实现了`Deref`指向其内部数据,`Drop`当 //`MutexGuard`离开作用域时自动释放锁
let text = "hello world wonderful word"; letmut map = HashMap::new(); for word in text.split_whitespace(){ let count = map.entry(word).or_insert(0); *count += 1; } //这段将在`map`中存储`text`中个单词出现次数
let teams = vec![String::from("Blue"), String::from("Yello")]; let initial_scores = vec![10, 30]; let scores: HashMap<_,_> = teams.iter.zip(initial_scores.iter()).collect(); //`collect`可能返回很多不同的数据结构,需要显式指定`scores` //的类型`HashMap<_,_>`
let team_name = String::from("Blue"); let team_score = scores.get(&team_name);
for (key, val) in &scores{ println!("{}:{}", key, val); }
implDropfor CustomSmartPointer{ fndrop(&mutself){ println!("Dropping CustomSmartPointer with data `{}`!", self.data); } }
fnmain(){ let c = CustomSmartPointer{ data: String::from("pointer1")}; let d = CustomSmartPointer{ data: String::from("pointer2")}; println!("CustomSmartPointer created!"); }
输出顺序如下,变量以被创建时相反的顺序丢弃
1 2 3
CustomSmartPointer created! Dropping CustomSmartPointer with data `pointer1`! Dropping CustomSmartPointer with data `pointer2`!
fnman(){ let c = CustomSmartPointer{ data: String::from("some data")}; println!("CumstomSmartPointer Created"); drop(c); //调用`std::mem::drop`函数,不是`c.drop()`方法 println!("CustomSmartPointer dropped before the end of main");
Box<T>
在堆上存储数据,而栈上存放指向堆数据的指针,常用于
类型编译时大小未知,而想要在确切大小的上下文中使用
大量数据希望在拷贝时不转移所有权
只关心数据是否实现某个trait而不是其具体的类型
(trait对像)
1 2 3 4
let b = Box::new(5); println!("b = {}", b); //可以像数据存储在栈上一样访问数据 //box离开作用域时,栈上和指向的堆上的数据都被释放
fnmain(){ let a = Rc::new(Cons(5, Rc::new(Cons(10, Rc::new(Nil))))); println!("count after creating a = {}", Rc::strong_count(&a)); //1
let b = Cons::(3, Rc::clone(&a)); //`Rc::clone`并不像大多数`clone`方法一样对所有数据 //进行深拷贝,只会增加引用计数,允许`a`和`b`**共享** //`Rc`中数据的所有权 //这里可以调用`a.clone()`代替`Rc::clone(&a)`,但是 //习惯上使用`Rc::cloen(&a)` println!("count after creating b = {}", Rc::strong_count(&a)); //2
{ let c = Cons::(4, Rc::clone(&a)); println!("count after creating c = {}", Rc::strong_count(&a)); //3 }
println!("count after c goes out of scope = {}", Rc::strong_count(&a)); //2 }
pubfnset_value(&mutself, value:usize){ self.value = value; let percentage_of_max = self.max asf64 / self.max asf64; if percentage_of_max >= 0.75{ self.messenger.send("Warning: over 75% of quota has been used!"); } }
}
#[cfg(test)] mod tests{ use supper::*; use std::cell:RefCell;
use List::{Cons, Nil}; use std::rc::Rc; use std::cell::RefCell;
fnmain(){ let value = Rc::new(RefCell::new(5)); let a = Rc::new(Cons(Rc::clone(&value), Rc::new(Nil))); let b = Cons(Rc::new(RefCell::new(6)), Rc::clone(&a)); let c = Cons(Rc::new(RefCell::new(10)), Rc::clone(&a)); *value.borrow_value += 10; println!("a after = {:?}", a); println!("b after = {:?}", b); println!("c after = {:?}", c); }