IOS蓝牙连接和发送数据

首先要确定蓝牙是否打开
本文使用的是 Objective-C语言
1.新建一个蓝牙帮助类BlueHelp
并导入

pragma mark – CBPeripheralDelegate
//只要扫描到服务就会调用,其中的外设就是服务所在的外设
– (void)peripheral:(CBPeripheral )peripheral didDiscoverServices:(NSError )error{
if (error){
NSLog(@”扫描服务出现错误,错误原因:%@”,error);
}else{
//获取外设中所扫描到的服务
NSArray *services = peripheral.services;
for (CBService *service in services){
//拿到需要扫描的服务,例如打印一些服务数据
//把所有的service打印出来
NSLog(@”service is :%@”,service);
//从需要的服务中查找需要的特征
//从peripheral的services中扫描特征
[peripheral discoverCharacteristics:nil forService:service];
}
}
}

//只要扫描到特征就会调用,其中的外设和服务就是特征所在的外设和服务
– (void)peripheral:(CBPeripheral )peripheral didDiscoverCharacteristicsForService:(CBService )service error:(NSError *)error{
if (error){
NSLog(@”扫描特征出现错误,错误原因:%@”,error);
}else{
//拿到服务中所有的特征
NSArray *characteristics = service.characteristics;
//遍历特征,拿到需要的特征进行处理
for (CBCharacteristic *characteristic in characteristics){
NSLog(@”所有的特征为:%@”,characteristic.UUID.UUIDString);
//如果是温度数据处理
if([characteristic.UUID.UUIDString isEqualToString:@”你自己的特征值”]){
//将全部的特征信息打印出来
_peripheral = peripheral;
scperipheral = peripheral;
[peripheral setNotifyValue:YES forCharacteristic:characteristic];
NSLog(@”%@”,characteristic);
}
//这里是发送 设备设置蓝牙发送温度数据的值
else if([characteristic.UUID.UUIDString isEqualToString:@”你自己的特征值”]){
writecharacteristic = characteristic;
[peripheral setNotifyValue:YES forCharacteristic:characteristic];
NSLog(@”写入的值为:%@”,characteristic);
}
//如果是ota进行ota升级
else if([characteristic.UUID.UUIDString isEqualToString:@”你需要的特征值”]){
_peripheral = peripheral;
scperipheral = peripheral;
writeOtacharacteristic = characteristic;
//设置通知
[peripheral setNotifyValue:YES forCharacteristic:characteristic];
//NSLog(@”OTA升级了”);
isOTA = TRUE;
NSString *s = @”OTA”;
NSDictionary *tempOta = [NSDictionary dictionaryWithObject:s forKey:@”ota”];
[[NSNotificationCenter defaultCenter] postNotificationName:@”tempOTA” object:nil userInfo:tempOta];
}
//无键按钮DFU
else if([characteristic.UUID.UUIDString isEqualToString:@”你自己需要的特征值”]){
writeDfucharacteristic = characteristic;
[peripheral setNotifyValue:YES forCharacteristic:characteristic];
NSLog(@”写入的OTA值为:%@”,characteristic);
}
}
}
}

/*
* 获取所有的温度更新数据
* 接收蓝牙发送过来的温度数据 并经过解析和转换
*/
– (void)peripheral:(CBPeripheral )peripheral didUpdateValueForCharacteristic:(CBCharacteristic )characteristic error:(NSError *)error
{
if ([characteristic.UUID isEqual:BOOT_LOADER_CHARACTERISTIC_UUID])
{
uint8_t dataPointer = (uint8_t ) [characteristic.value bytes];
NSString *errorCode = [NSString stringWithFormat:@”0x%2x”,dataPointer[1]];
errorCode = [errorCode stringByReplacingOccurrencesOfString:@” ” withString:@”0”];

 

1     // Checking the error code from the response
2     if ([errorCode isEqualToString:SUCCESS]&&commandArray.count>0)
3     {
4         if ([[commandArray objectAtIndex:0] isEqual:@(ENTER_BOOTLOADER)])
5         {
6             [self getBootLoaderDataFromCharacteristic:characteristic];
7         }
8         else if ([[commandArray objectAtIndex:0] isEqual:@(GET_FLASH_SIZE)])
9         {
10             [self getFlashDataFromCharacteristic:characteristic];
11         }
12         else if ([[commandArray objectAtIndex:0] isEqual:@(SEND_DATA)])
13         {
14             _isWritePacketDataSuccess = YES;
15             [_userDefaults setBool:_isWritePacketDataSuccess forKey:@”WriteSuccess”];
16         }
17         else if ([[commandArray objectAtIndex:0] isEqual:@(PROGRAM_ROW)])
18         {
19             _isWritePacketDataSuccess = YES;
20             [_userDefaults setBool:_isWritePacketDataSuccess forKey:@”WriteSuccess”];
21         }
22
23         else if ([[commandArray objectAtIndex:0] isEqual:@(VERIFY_ROW)])
24         {
25             [self getRowCheckSumFromCharacteristic:characteristic];
26         }
27         else if([[commandArray objectAtIndex:0] isEqual:@(VERIFY_CHECKSUM)])
28         {
29             [self checkApplicationCheckSumFromCharacteristic:characteristic];
30         }
31
32         if (cbCharacteristicUpdationHandler != nil)
33         {
34             cbCharacteristicUpdationHandler(YES,[commandArray objectAtIndex:0],nil);
35             [commandArray removeObjectAtIndex:0];
36         }
37
38     }
39     else
40     {
41         if(commandArray.count>0){
42             if ([[commandArray objectAtIndex:0] isEqual:@(PROGRAM_ROW)])
43             {
44                 _isWritePacketDataSuccess = NO;
45             }
46             else if ([[commandArray objectAtIndex:0] isEqual:@(SEND_DATA)])
47             {
48                 _isWritePacketDataSuccess = NO;
49             }
50             if (cbCharacteristicUpdationHandler != nil)
51             {
52                 cbCharacteristicUpdationHandler(YES,[commandArray objectAtIndex:0],nil);
53                 [commandArray removeObjectAtIndex:0];
54             }
55         }
56     }
57 }
58 if(!isOTA&&!_isSendData){
59     NSString *temps=[self getTempData:characteristic];
60     NSArray *ss = [temps componentsSeparatedByString:@”,”];
61     NSString *tempWendu =ss[0];
62     NSString *tempSymbol = ss[1];
63
64     self.currentDate = [NSDate date];
65
66     NSString *dateString = [_dateformatter stringFromDate:self.currentDate];
67
68     NSLog(@” ==save is time=== :%@”,dateString);
69
70     NSDate *logDate = [_dateformatter dateFromString:dateString];
71     long logTime= (long)[logDate timeIntervalSince1970];
72     if(temps!=nil&&![_bluename isEqualToString:@””]&&_bluename!=nil&&_bluename!=NULL){ //把数据存入到数据库
73     NSString *a = [_userDefaults objectForKey:@”tempUnit”];
74     //如果是华氏度的时候一定要把它转为摄氏度之后再来保存数据 以便数据的统一性
75     if([a isEqualToString:@”°F”]){
76         float floatString = [tempWendu floatValue];
77
78         float aa = [_normalUtil convertFahrenheitToCelcius:floatString];
79
80         NSString *ftempWendu =  [NSString stringWithFormat:@”%.1f”,aa];
81         NSString *ftempSymbol = @”°C”;
82
83         [_tempDao saveTempname:_bluename saveTempaddre:_blueaddre saveTempwenduname:ftempSymbol saveTempwendu:ftempWendu saveTemptime:logTime];
84         }else{
85
86             [_tempDao saveTempname:_bluename saveTempaddre:_blueaddre saveTempwenduname:tempSymbol saveTempwendu:tempWendu saveTemptime:logTime];
87         }
88
89         NSLog(@” ==save is success=== :%ld”,logTime);
90     }
91
92     //当读取到数据的时候就要存入数据 以后用来蓝牙自动的去连接
93     if(_saveAutoOnce){
94         [_userDefaults setObject:_bluename forKey:@”autoBlueName”];
95         [_userDefaults setObject:_blueaddre forKey:@”autoBlueAddre”];
96         _saveAutoOnce = false;
97     }
98
99     NSString * tp = [temps stringByAppendingString:@”,”];
100
101     NSString * tempp = [tp stringByAppendingString:_blueaddre];
102
103     NSDictionary *tempDict = [NSDictionary dictionaryWithObject:tempp forKey:@”temp”];
104
105     [[NSNotificationCenter defaultCenter] postNotificationName:@”tempNofiction” object:nil userInfo:tempDict];
106 }

}

上面这些代码可以不看 我写的是一些数据的转换
下面我们可以看下蓝牙写入数据
//也可以自定义主要是给外部调用
//发送数据

-(void)writeBlueValue:(NSString *)value{
_isSendData = TRUE;
[self writeValue:value forCharacteristic:writecharacteristic];
}

/*
这个是给蓝牙发送数据用的
*/
-(void)writeValue:(NSString )value forCharacteristic:(CBCharacteristic )characteristic
{
// NSData *data = [value dataUsingEncoding:4];
NSData *data = [_normalUtil stringToBytes:value];
NSLog(@”send data is:%@:characteristic:%@”,data,writecharacteristic);
//is no write bluetooth data
if(writecharacteristic.properties & CBCharacteristicPropertyWriteWithoutResponse)
{
//send phone on bluetooth data
[selectPeriperal writeValue:data forCharacteristic:writecharacteristic type:CBCharacteristicWriteWithoutResponse];
}else
{
[selectPeriperal writeValue:data forCharacteristic:writecharacteristic type:CBCharacteristicWriteWithResponse];

1 }
2 //发送完成后 又要它归位
3 _isSendData = FALSE;
4 NSLog(@”已经向外设%@的特征值%@写入数据”,selectPeriperal.name,writecharacteristic.description);

}

一般发送数据都需要用到 NSData数据类型格式下面我有几个方法
/**
* Method to convert hex to byteArray。这里是将16进制转换为NSData
*/

-(NSMutableData )dataFromHexString:(NSString )string
{
NSMutableData *data = [NSMutableData new];
NSCharacterSet *hexSet = [[NSCharacterSet characterSetWithCharactersInString:@”0123456789ABCDEF “] invertedSet];

 

1 // Check whether the string is a valid hex string. Otherwise return empty data
2 if ([string rangeOfCharacterFromSet:hexSet].location == NSNotFound) {
3
4     string = [string lowercaseString];
5     unsigned char whole_byte;
6     char byte_chars[3] = {‘\0′,’\0′,’\0’};
7     int i = 0;
8     int length = (int)string.length;
9
10     while (i < length-1)
11     {
12         char c = [string characterAtIndex:i++];
13
14         if (c < ‘0’ || (c > ‘9’ && c < ‘a’) || c > ‘f’)
15             continue;
16         byte_chars[0] = c;
17         byte_chars[1] = [string characterAtIndex:i++];
18         whole_byte = strtol(byte_chars, NULL, 16);
19         [data appendBytes:&whole_byte length:1];
20     }
21 }
22 return data;

}

还有一种是
//字符串转为数组
-(NSData )stringToBytes:(NSString )string{
int a = [string intValue];
NSData *aData = [string dataUsingEncoding: NSUTF8StringEncoding];
Byte testByte = (Byte )[aData bytes];
testByte[0] = (Byte)(a>>24&0xff);
testByte[1] = (Byte) (a>>16&0xff);
testByte[2] = (Byte)(a>>8&0xff);
testByte[3] = (Byte)(a&0xff);

1 NSData *adata = [[NSData alloc] initWithBytes:testByte length:4];
2
3 return adata;

这些方法比较常用的
好了基本思路就这样 源代码 过段时间放上来 。

【Android】短信应用——短信信息实时获取

我们知道,只需通过代码就可以读到收件箱中的短信,发件箱中的短信;但是却没办法在短信发来的瞬间获取;如果我们在短信发来的一瞬间能得到相应的信息内容,那么我们就可以依次来展开很多应用了——也就是通过短信去远程操作一部手机。

 

如果想实时获取,就需要调用receiver了,写一个监听类,这样我们就可以实时获取短息信息了。

 

预览图:%title插图%num

 

还是来看看代码吧。

首先,我们需要创建一个监听类SMSBroadcastReceiver,让他去继承BroadcastReceiver。

再来初始化一个常量ACTION,并赋短信相关参数值。

 

android.provider.Telephony.SMS_RECEIVED
接着创建onReceive方法。

然后用getAction去监听手机短信相关动态,利用StringBuffer来保存短信信息。

 

再然后主要代码了。

%title插图%num
代码中的SMSAddress为发送短信的号码,SMSContent为短信内容。

 

要想看到是否成功获取,*简单的方法就是把这两个参数打印出来。

1|System.out.println(“发送号码:” + SMSAddress + “\n” + “短信内容:”
2|                                         + SMSContent);

不过要把他们加入for循环中,因为当新信息发来时,SMSAddress和SMSContent将被替换。

因此如果要是做应用时,也是在for循环中判断的。

*后要记得在Manifest.xml中注册监听器。

 

<receiver android:name=”cn.etzmico.SMSBroadcastReceiver”>
<intent-filter>
<action android:name=”android.provider.Telephony.SMS_RECEIVED”></action>
</intent-filter>
</receiver>

 

同时要加上权限。

 

<uses-permission android:name=”android.permission.RECEIVE_SMS”></uses-permission>
这样,我们运行程序后,只要有短信接收,SMSAddress和SMSContent就会被赋值。

 

这里顺便补充一个知识点,关于Eclipse程序的。

相信很多初学者不知道,Eclipse自带一个发短信插件,可以实现给虚拟机发送短信。这样,我们在做短信应用的时候,就不用同时启动多台虚拟机了……

如何操作呢?方法如下。

1.点击菜单栏中的 Window 窗口。

2.找到哦啊其中的 Show View 目录。

3. 选择 Other…。

%title插图%num

然后我们发现会弹出一个窗口。

%title插图%num

4,为了便于操作,我们在弹出的窗口的搜索栏中,直接输入 Emulator Control。

%title插图%num

5.点击列表中的 Emulator Control,再点OK;或者直接双击。

 

这样就出现了一个窗口,其中有很多参数。

其他的以后有机会再做介绍,我们这次至用到其中4个。

%title插图%num

如图所示,我们只需要输入对应的参数,选择需要的类型,*后点发送就可以了。

 

PS:有的人奇怪为什么灰色,没法输入,没法选择,那是因为你没有选中模拟器。这个插件只能同时给一个模拟器发送消息。关于模拟器的选择,和调用Emulator Control的方法差不多,区别只是在输入Emulator Control的时候输入 Devices 就可以了。你当前选中哪个模拟器了,就会给哪个模拟器发送消息,不需要输入模拟器号码。

python算法与数据结构之二分查找

python算法与数据结构之二分查找

python算法与数据结构之二分查找
温馨提示:看明白不代表掌握,*好自己亲自手写n遍。正所谓:纸上得来终觉浅,*知此事要躬行
二分查找,首先要求列表是有序列表!

%title插图%num
def binary_search(li, val):
left = 0
right = len(li) – 1
while left <= right: # 候选区有值
mid = (left + right) // 2 # //向下取整
if li[mid] == val:
return mid # 返回索引
elif li[mid] > val: # 要查找的val在mid左侧
right = mid – 1
else:
left = mid + 1
else:
return None # 找不到返回None

li = [2, 3, 4, 6, 8, 10]
print(binary_search(li, 8))

SSH连接AWS服务器的方法

一、获取服务器连接指令

拿到机器后,使用ssh连接服务器,用户名是ubuntu。

%title插图%num

%title插图%num

打开命令行,输入上面的那条指令,将root换成ubuntu。

%title插图%num

注:如果提示下面的问题

%title插图%num

则调整安全组

%title插图%num

%title插图%num

二、检查显卡驱动是否安装

这里有个坑就是显卡驱动。尽管镜像中本来安装好了驱动,由于挂载盘特性,驱动会可能被系统屏蔽,需要重新安装,或者是屏蔽某系统文件。

首先,检查是否有驱动:

nvidia-smi

如果显示:

%title插图%num

则已经有驱动了,不需要安装。

否则,提示这个

%title插图%num

则你需要安装驱动。安装过程见《AWS服务器中装CUDA》。

 

iOS蓝牙开发数据实时传输

随着iOS项目开发  很多app需要通过蓝牙与设备连接

蓝牙开发注意:

先定义中心设备和外围设备以及遵守蓝牙协议

@interface ViewController()<CBCentralManagerDelegate,CBPeripheralDelegate>
@property (strong, nonatomic) CBCentralManager *manager;
@property (nonatomic, strong) CBPeripheral *peripheral;

@property (nonatomic, weak)NSTimer * connentTimer;

@end

8313

 

再实现delegate方法

  1. 判断蓝牙状态,如成功则扫描指定UUID设备(如不指定UUID,则无法后台持续连接)
  2. 当发现指定设备后,连接该设备
  3. 当连接指定外围设备成功,编写定时器,每秒读取1次RSSI
  4. 当监听到失去和外围设备连接,重新建立连接
  5. 当读取到RSSI值,打印出它的值

 

  1. 1 //蓝牙状态
    2 – (void)centralManagerDidUpdateState:(CBCentralManager *)central
    3 {
    4     NSString * state = nil;
    5     switch ([central state])
    6     {
    7         case CBCentralManagerStateUnsupported:
    8             state = @”The platform/hardware doesn’t support Bluetooth Low Energy.”;
    9             break;
    10
    11         case CBCentralManagerStateUnauthorized:
    12             state = @”The app is not authorized to use Bluetooth Low Energy.”;
    13             break;
    14              //尚未打开蓝牙
    15         case CBCentralManagerStatePoweredOff:
    16             state = @”Bluetooth is currently powered off.”;
    17             break;
    18              //连接成功
    19         case CBCentralManagerStatePoweredOn:
    20             [self.manager scanForPeripheralsWithServices:nil options:nil];
    21             state = @”work”;
    22             break;
    23         case CBCentralManagerStateUnknown:
    24         default:
    25             ;
    26     }
    27
    28     NSLog(@”Central manager state: %@”, state);
    29 }
    30 //查找设备
    31 – (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
    32 {
    33       //每个蓝牙设备有自己唯一的标识符,根据标识符确认自己要连接的设备
    34     if ([peripheral.identifier isEqual:self.peripheral.identifier])
    35     {
    36         self.peripheral = peripheral;
    37         //数据连接定时器
    38         self.connentTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(connentPeripheral) userInfo:@”timer” repeats:YES];
    39         [self.connentTimer fire];
    40     }
    41 }
    42
    43 – (void)connentPeripheral {
    44     //连接外设
    45     self.manager.delegate = self;
    46     [self.manager connectPeripheral:_peripheral options:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:CBConnectPeripheralOptionNotifyOnDisconnectionKey]];
    47
    48 }
    49
    50 //连接成功后调用
    51 – (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
    52 {
    53     NSLog(@”Did connect to peripheral: %@,%@”, peripheral,peripheral.name);
    54     [peripheral setDelegate:self];  //查找服务
    55     [peripheral discoverServices:nil];
    56     [self.connentTimer invalidate];
    57     //监测设备是否断开了
    58 //    [self createWorkDataSourceWithTimeInterval:1];
    59 }
    60 //当监听到失去和外围设备连接,重新建立连接
    61 //这个方法是必须实现的,因为蓝牙会中断连接,正好触发这个方法重建连接。重建连接可能造成数秒后才能读取到RSSI。
    62
    63 – (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
    64 {
    65     [self.manager connectPeripheral:peripheral options:nil];
    66 }
    67
    68 – (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
    69 {
    70     NSLog(@”%@”,error.description);
    71 }
    72
    73 //返回的蓝牙服务通知通过代理实现
    74 – (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
    75 {
    76     if (error)
    77     {
    78         NSLog(@”Discovered services for %@ with error: %@”, peripheral.name, [error localizedDescription]);
    79         return;
    80     }
    81     for (CBService *service in peripheral.services)
    82     {
    83 //        NSLog(@”Service found with UUID: %@”, service.UUID.UUIDString);
    84         //发现服务
    85         if ([service.UUID isEqual:[CBUUID UUIDWithString:@”180D”]])//heart rate
    86         {
    87             //在一个服务中寻找特征值
    88             [peripheral discoverCharacteristics:nil forService:service];
    89         }
    90     }
    91 }
    92
    93 //返回的蓝牙特征值通知通过代理实现
    94 – (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
    95 {
    96     if (error)
    97     {
    98         NSLog(@”Discovered characteristics for %@ with error: %@”, service.UUID, [error localizedDescription]);
    99         return;
    100     }
    101     for (CBCharacteristic * characteristic in service.characteristics)
    102     {
    103         NSLog(@”characteristic:%@”,characteristic);
    104         if( [characteristic.UUID isEqual:[CBUUID UUIDWithString:@”2A37″]])
    105         {
    106
    107             [self notification:service.UUID characteristicUUID:characteristic.UUID peripheral:peripheral on:YES];
    108 //            [self.peripheral setNotifyValue:YES forCharacteristic:characteristic];
    109         }
    110     }
    111 }
    112
    113 //处理蓝牙发过来的数据
    114 – (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
    115 {
    116
    117 }
    118
    119 -(void) notification:(CBUUID *) serviceUUID characteristicUUID:(CBUUID *)characteristicUUID peripheral:(CBPeripheral *)p on:(BOOL)on
    120 {
    121     CBService *service = [self getServiceFromUUID:serviceUUID p:p];
    122     if (!service)
    123     {
    124         //        if (p.UUID == NULL) return; // zach ios6 addedche
    125         //        NSLog(@”Could not find service with UUID on peripheral with UUID \n”);
    126         return;
    127     }
    128     CBCharacteristic *characteristic = [self getCharacteristicFromUUID:characteristicUUID service:service];
    129     if (!characteristic)
    130     {
    131         //        if (p.UUID == NULL) return; // zach ios6 added
    132         //        NSLog(@”Could not find characteristic with UUID  on service with UUID  on peripheral with UUID\n”);
    133         return;
    134     }
    135     [p setNotifyValue:on forCharacteristic:characteristic];
    136
    137 }
    138
    139 -(CBService *) getServiceFromUUID:(CBUUID *)UUID p:(CBPeripheral *)p
    140 {
    141
    142     for (CBService* s in p.services)
    143     {
    144         if ([s.UUID isEqual:UUID]) return s;
    145     }
    146     return nil; //Service not found on this peripheral
    147 }
    148 -(CBCharacteristic *) getCharacteristicFromUUID:(CBUUID *)UUID service:(CBService*)service {
    149
    150     for (CBCharacteristic* c in service.characteristics)
    151     {
    152         if ([c.UUID isEqual:UUID]) return c;
    153     }
    154     return nil; //Characteristic not found on this service
    155 }

python图片爬虫

python图片爬虫

先附上代码
import urllib.request
import requests
import re

#爬取网页地址
url = “http://news.ifeng.com/a/20161115/50258273_0.shtml”

#获取网页
html = requests.get(url)
#打印出网页信息
print (html.content.decode())

#利用正则表达式获取图片网址
reg = r’src=”(.*?\.jpg)”‘
img = re.compile(reg)
imglist = re.findall(img, html.content.decode())
#打印出所有的图片链接
print (imglist)

#下载图片
x = 0
for imgurl in imglist:
urllib.request.urlretrieve(imgurl,’E:\\python\\爬虫数据\\%s.jpg’%x)
x = x + 1

PaddlePaddle:CNN对Cifar10图像分类

PaddlePaddle:CNN对Cifar10图像分类(2)

d
PaddlePaddle:CNN对Cifar10图像分类(2)
在PaddlePaddle:CNN对Cifar10图像分类(1)中已经详细介绍和讲解了PaddlePaddle深度学习框架、卷积神经网络CNN的层级结构以及Cifar10数据集加载的过程,下面通过2个经典的卷积神经网络结构AlexNet和ResNet50对Cifar10数据集进行图像分类。

文章目录
PaddlePaddle:CNN对Cifar10图像分类(2)
(一)基于PaddlePaddle实现AlexNet与ResNet50
1.AlexNet的实

%title插图%num
(1)AlexNet的网络结构
(2)AlexNet的代码实现
2.ResNet的实现
ResNet的代码实现
(二)输入参数与日志记录
(三)基于 PaddlePaddle 的模型训练与测试
(四)训练结果
1.python paddle_trainer.py –model=AlexNet
2.python paddle_trainer.py –model=ResNet50
(一)基于PaddlePaddle实现AlexNet与ResNet50
1.AlexNet的实现
(1)AlexNet的网络结构

*个卷积层

输入的图片大小为:224*224*3(或者是227*227*3)

*个卷积层为:11*11*96即尺寸为11*11,有96个卷积核,步长为4,卷积层后跟ReLU,因此输出的尺寸为 224/4=56,去掉边缘为55,因此其输出的每个feature map 为 55*55*96,同时后面跟LRN层,尺寸不变.

*大池化层,核大小为3*3,步长为2,因此feature map的大小为:27*27*96.

第二层卷积层

输入的tensor为27*27*96

卷积和的大小为: 5*5*256,步长为1,尺寸不会改变,同样紧跟ReLU,和LRN层.

*大池化层,和大小为3*3,步长为2,因此feature map为:13*13*256

第三层至第五层卷积层

输入的tensor为13*13*256

第三层卷积为 3*3*384,步长为1,加上ReLU

第四层卷积为 3*3*384,步长为1,加上ReLU

第五层卷积为 3*3*256,步长为1,加上ReLU

第五层后跟*大池化层,核大小3*3,步长为2,因此feature map:6*6*256

第六层至第八层全连接层

接下来的三层为全连接层,分别为:

FC : 4096 + ReLU
FC:4096 + ReLU
FC: 1000 *后一层为softmax为1000类的概率值.
AlexNet中的trick

AlexNet将CNN用到了更深更宽的网络中,其效果分类的精度更高相比于以前的LeNet,其中有一些trick是必须要知道的.

ReLU的应用
AlexNet使用ReLU代替了Sigmoid,其能更快的训练,同时解决sigmoid在训练较深的网络中出现的梯度消失,或者说梯度弥散的问题.
Dropout随机失活
随机忽略一些神经元,以避免过拟合,
重叠的*大池化层
在以前的CNN中普遍使用平均池化层,AlexNet全部使用*大池化层,避免了平均池化层的模糊化的效果,并且步长比池化的核的尺寸小,这样池化层的输出之间有重叠,提升了特征的丰富性.
提出了LRN层
局部响应归一化,对局部神经元创建了竞争的机制,使得其中响应小打的值变得更大,并抑制反馈较小的.
使用了GPU加速计算
使用了gpu加速神经网络的训练
(2)AlexNet的代码实现
import paddle.fluid as fluid
import paddle.fluid.dygraph.nn as nn

class AlexNet(fluid.dygraph.Layer):
def __init__(self, in_size, in_channels, num_classes):
super(AlexNet, self).__init__()
self.num_classes = num_classes
# 卷积层
self.conv1 = nn.Conv2D(num_channels=in_channels, num_filters=96, filter_size=5, stride=1, padding=2, act=’relu’)
self.pool1 = nn.Pool2D(pool_size=2, pool_stride=2, pool_type=’max’)
self.conv2 = nn.Conv2D(num_channels=96, num_filters=256, filter_size=5, stride=1, padding=2, act=’relu’)
self.pool2 = nn.Pool2D(pool_size=2, pool_stride=2, pool_type=’max’)
self.conv3 = nn.Conv2D(num_channels=256, num_filters=384, filter_size=3, stride=1, padding=1, act=’relu’)
self.conv4 = nn.Conv2D(num_channels=384, num_filters=384, filter_size=3, stride=1, padding=1, act=’relu’)
self.conv5 = nn.Conv2D(num_channels=384, num_filters=256, filter_size=3, stride=1, padding=1, act=’relu’)
self.pool5 = nn.Pool2D(pool_size=2, pool_stride=2, pool_type=’max’)
out_size = in_size // 8
# 全连接层
self.fc1 = nn.Linear(input_dim=256 * out_size * out_size, output_dim=2048, act=’relu’)
self.dropout1 = nn.Dropout(p=0.5)
self.fc2 = nn.Linear(input_dim=2048, output_dim=2048, act=’relu’)
self.dropout2 = nn.Dropout(p=0.5)
self.fc3 = nn.Linear(input_dim=2048, output_dim=self.num_classes)

def forward(self, x, y=None):
# 卷积层
x = self.conv1(x)
x = self.pool1(x)
x = self.conv2(x)
x = self.pool2(x)
x = self.conv3(x)
x = self.conv4(x)
x = self.conv5(x)
x = self.pool5(x)
# 全连接层
x = fluid.layers.reshape(x, (x.shape[0], -1))
x = self.fc1(x)
x = self.dropout1(x)
x = self.fc2(x)
x = self.dropout2(x)
x = self.fc3(x)
if y is not None:
loss = fluid.layers.softmax_with_cross_entropy(x, y)
return x, loss
else:
return x

def forward_size(self, x, y=None):
print(‘Paddle-AlexNet’)
print(‘input’, x.shape)
# 卷积层
x = self.conv1(x)
print(‘conv1’, x.shape)
x = self.pool1(x)
print(‘pool1’, x.shape)
x = self.conv2(x)
print(‘conv2’, x.shape)
x = self.pool2(x)
print(‘pool2’, x.shape)
x = self.conv3(x)
print(‘conv3’, x.shape)
x = self.conv4(x)
print(‘conv4’, x.shape)
x = self.conv5(x)
print(‘conv5’, x.shape)
x = self.pool5(x)
print(‘pool5’, x.shape)
# 全连接层
x = fluid.layers.reshape(x, (x.shape[0], -1))
x = self.fc1(x)
x = self.dropout1(x)
print(‘fc1’, x.shape)
x = self.fc2(x)
x = self.dropout2(x)
print(‘fc2’, x.shape)
x = self.fc3(x)
print(‘fc3’, x.shape)
if y is not None:
loss = fluid.layers.softmax_with_cross_entropy(x, y)
print(‘loss’, loss.shape)

if __name__ == ‘__main__’:
with fluid.dygraph.guard(fluid.CPUPlace()):
in_size = 32
x = fluid.layers.zeros((2, 3, in_size, in_size), dtype=’float32′)
y = fluid.layers.randint(0, 10, (2, 1), dtype=’int64′)
model = AlexNet(in_size=in_size, in_channels=3, num_classes=10)
model.forward_size(x, y)
predict, loss = model(x, y)
print(predict.shape, loss.shape)

2.ResNet的实现
ResNet的代码实现
class DistResNet():
def __init__(self, is_train=True):

self.is_train = is_train
self.weight_decay = 1e-4

def net(self, input, class_dim=10):

depth = [3, 3, 3, 3]
num_filters = [16, 32, 32, 64]

conv = self.conv_bn_layer(
input=input, num_filters=16, filter_size=3, act=’elu’)
conv = fluid.layers.pool2d(
input=conv,
pool_size=3,
pool_stride=2,
pool_padding=1,
pool_type=’max’)

for block in range(len(depth)):
for i in range(depth[block]):
conv = self.bottleneck_block(
input=conv,
num_filters=num_filters[block],
stride=2 if i == 0 and block != 0 else 1)
conv = fluid.layers.batch_norm(input=conv, act=’elu’)
print(conv.shape)
pool = fluid.layers.pool2d(
input=conv, pool_size=2, pool_type=’avg’, global_pooling=True)
stdv = 1.0 / math.sqrt(pool.shape[1] * 1.0)
out = fluid.layers.fc(input=pool,
size=class_dim,
act=”softmax”,
param_attr=fluid.param_attr.ParamAttr(
initializer=fluid.initializer.Uniform(-stdv,
stdv),
regularizer=fluid.regularizer.L2Decay(self.weight_decay)),
bias_attr=fluid.ParamAttr(
regularizer=fluid.regularizer.L2Decay(self.weight_decay))
)
return out

def conv_bn_layer(self,
input,
num_filters,
filter_size,
stride=1,
groups=1,
act=None,
bn_init_value=1.0):
conv = fluid.layers.conv2d(
input=input,
num_filters=num_filters,
filter_size=filter_size,
stride=stride,
padding=(filter_size – 1) // 2,
groups=groups,
act=None,
bias_attr=False,
param_attr=fluid.ParamAttr(regularizer=fluid.regularizer.L2Decay(self.weight_decay)))
return fluid.layers.batch_norm(
input=conv, act=act, is_test=not self.is_train,
param_attr=fluid.ParamAttr(
initializer=fluid.initializer.Constant(bn_init_value),
regularizer=None))

def shortcut(self, input, ch_out, stride):
ch_in = input.shape[1]
if ch_in != ch_out or stride != 1:
return self.conv_bn_layer(input, ch_out, 1, stride)
else:
return input

def bottleneck_block(self, input, num_filters, stride):
conv0 = self.conv_bn_layer(
input=input, num_filters=num_filters, filter_size=1, act=’relu’)
conv1 = self.conv_bn_layer(
input=conv0,
num_filters=num_filters,
filter_size=3,
stride=stride,
act=’relu’)
conv2 = self.conv_bn_layer(
input=conv1, num_filters=num_filters * 4, filter_size=1, act=None, bn_init_value=0.0)

short = self.shortcut(input, num_filters * 4, stride)

return fluid.layers.elementwise_add(x=short, y=conv2, act=’relu’)

(二)输入参数与日志记录
import os
import sys
import logging
import argparse

def setup_logger(name, save_dir=’./jobs’, log_file=’train.log’):
logger = logging.getLogger(name)
logger.propagate = False
logger.setLevel(logging.INFO)
# stdout
stdout_handler = logging.StreamHandler(stream=sys.stdout)
stdout_handler.setLevel(logging.INFO)
formatter = logging.Formatter(‘[%(asctime)s %(filename)s %(levelname)s] %(message)s’)
stdout_handler.setFormatter(formatter)
logger.addHandler(stdout_handler)
# file
if save_dir is not None:
if not os.path.exists(save_dir):
os.makedirs(save_dir)
file_handler = logging.FileHandler(os.path.join(save_dir, log_file), mode=’w’)
file_handler.setLevel(logging.INFO)
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
return logger

def parse_args():
parser = argparse.ArgumentParser(description=’Training With PaddlePaddle or PyTorch.’)
# cuda
parser.add_argument(‘–no-cuda’, action=’store_true’, default=False)
# dataset
parser.add_argument(‘–dataset’, type=str, choices=(‘mnist’, ‘cifar10′), default=’mnist’)
# epochs
parser.add_argument(‘–epochs’, type=int, default=10)
# lr
parser.add_argument(‘–lr’, type=float, default=0.01)
# weight_decay
parser.add_argument(‘–weight_decay’, type=float, default=1e-4)
# batch_size
parser.add_argument(‘–batch_size’, type=int, default=100)
# logging
parser.add_argument(‘–log_iter’, type=int, default=100)
args = parser.parse_args()
return args

(三)基于 PaddlePaddle 的模型训练与测试
import os
import logging
import numpy as np
import paddle.fluid as fluid
from paddle_models import AlexNet
from datasets import mnist, cifar10, data_loader
from utils import setup_logger, parse_args

def tester(model, data_loader, place=fluid.CPUPlace()):
model.eval()
correct, total = 0, 0
with fluid.dygraph.guard(place), fluid.dygraph.no_grad():
for batch_id, (batch_image, batch_label) in enumerate(data_loader(), 1):
# 准备数据
batch_image = fluid.dygraph.to_variable(batch_image)
batch_label = fluid.dygraph.to_variable(batch_label.reshape(-1,))
# 前向传播
predict = fluid.layers.argmax(model(batch_image), axis=1)
correct += fluid.layers.reduce_sum(fluid.layers.equal(predict, batch_label).astype(‘int32′)).numpy()[0]
total += batch_label.shape[0]
return correct / total

def trainer(dataset=’mnist’, epochs=10, lr=0.01, weight_decay=1e-4, batch_size=100, no_cuda=False,
log_iter=100, job_dir=’./paddle_mnist’, logger=None):
if not os.path.exists(job_dir):
os.makedirs(job_dir)
if logger is None:
logger = logging
logger.basicConfig(level=logging.INFO)
if no_cuda:
place = fluid.CPUPlace()
else:
place = fluid.CUDAPlace(0)
# 训练数据
train_dataset, test_dataset = eval(dataset)()
train_loader = data_loader(train_dataset, batch_size=batch_size, shuffle=True)
test_loader = data_loader(test_dataset, batch_size=batch_size, shuffle=False)
logger.info(‘Dataset: {} | Epochs: {} | LR: {} | Weight Decay: {} | Batch Size: {} | GPU: {}’.format(dataset, epochs,
lr, weight_decay,
batch_size, not no_cuda))
train_loss = list()
test_accuracy = list()
iter = 0
with fluid.dygraph.guard(place):
# 分类模型
if dataset == ‘mnist’:
model = AlexNet(in_size=28, in_channels=1, num_classes=10)
elif dataset == ‘cifar10’:
model = AlexNet(in_size=32, in_channels=3, num_classes=10)
else:
raise ValueError(‘dataset should be in (mnist, cifar10)’)
model.train()
# 学习率
total_step = epochs * np.ceil(train_dataset[0].shape[0] / batch_size)
learning_rate = fluid.dygraph.PolynomialDecay(lr, total_step, 0, power=0.9)
# 优化器
optimizer = fluid.optimizer.MomentumOptimizer(learning_rate=learning_rate, momentum=0.9,
parameter_list=model.parameters(),
regularization=fluid.regularizer.L2Decay(weight_decay))
for epoch_id in range(1, epochs + 1):
for batch_id, (batch_image, batch_label) in enumerate(train_loader(), 1):
# 准备数据
batch_image = fluid.dygraph.to_variable(batch_image)
batch_label = fluid.dygraph.to_variable(batch_label)
# 前向传播
predict, loss = model(batch_image, batch_label)
avg_loss = fluid.layers.mean(loss)
# 反向传播
model.clear_gradients()
avg_loss.backward()
optimizer.minimize(avg_loss)
if batch_id % log_iter == 0:
logger.info(‘Epoch: {} | Iter: {} | Loss: {:.6f} | LR: {:.6f}’.format(epoch_id, batch_id, avg_loss.numpy()[0],
optimizer.current_step_lr()))
iter += log_iter
train_loss.append((avg_loss.numpy()[0], iter))
# 测试
accuracy = tester(model, test_loader, place)
logger.info(‘Epoch: {} | Acc: {:.4f}’.format(epoch_id, accuracy))
test_accuracy.append((accuracy, iter))
model.train()
# 保存模型参数
fluid.save_dygraph(model.state_dict(), os.path.join(job_dir, ‘epoch_%d’ % epochs))
logger.info(‘Model File: {}’.format(os.path.join(job_dir, ‘epoch_%d’ % epochs)))
# 保存训练损失与测试精度
train_loss = np.array(train_loss)
test_accuracy = np.array(test_accuracy)
train_loss.tofile(os.path.join(job_dir, ‘train_loss.bin’))
test_accuracy.tofile(os.path.join(job_dir, ‘test_accuracy.bin’))

if __name__ == ‘__main__’:
args = parse_args()
job_dir = ‘./paddle_’ + args.dataset
logger = setup_logger(‘paddle_’ + args.dataset, save_dir=job_dir)
trainer(job_dir=job_dir, logger=logger, **vars(args))

(四)训练结果
1.python paddle_trainer.py –model=AlexNet
2.python paddle_trainer.py –model=ResNet50

%title插图%num

参考资料:

1.基于 PaddlePaddle / PyTorch 实现 CIFAR-10 / MNIST 图像分类
2.PaddlePaddle官方教程文档

iOS蓝牙开发总结及Demo

1. 概念

BLE ,buletouch low energy,蓝牙4.0设备因为低耗电,所以也叫做BLE;
中心设备 ,用于扫描周边蓝牙外设的设备,比如我们上面所说的中心者模式,此时我们的手机就是中心设备;
外设 ,被扫描的蓝牙设备,比如我们上面所说的用我们的手机连接小米手环,这时候小米手环就是外设;
广播 ,外部设备不停的散播的蓝牙信号,让中心设备可以扫描到,也是我们开发中接收数据的入口;
服务(Service) ,外部设备在与中心设备连接后会有服务,可以理解成一个功能模块,中心设备可以读取服务,筛选我们想要的服务,并从中获取出我们想要特征。(外设可以有多个服务);
特征(Characteristic) ,服务中的一个单位,一个服务可以多个特征,而特征会有一个value,一般我们向蓝牙设备写入数据、从蓝牙设备读取数据就是这个value;
UUID ,区分不同服务和特征的唯一标识,使用该字端我们可以获取我们想要的服务或者特征(ps: 不同的中心设备(也可以说是不同的手机)对于同一台蓝牙设备,获取到的UUIDString可能是不一样的)。

2. CoreBluetooth框架

CoreBluetooth框架的核心其实是两个东西,peripheral和central, 可以理解成外设和中心。
图中两组api分别对应不同的业务场景,左侧叫做中心模式,就是以你的app作为中心,连接其他的外设的场景,而右侧称为外设模式,使用手机作为外设别其他中心设备操作的场景

蓝牙中心模式流程

1. 建立中心角色
2. 扫描外设(discover)
3. 连接外设(connect)
4. 扫描外设中的服务和特征(discover)
– 4.1 获取外设的services
– 4.2 获取外设的Characteristics,获取Characteristics的值,获取Characteristics的Descriptor和Descriptor的值
5. 与外设做数据交互(explore and interact)
6. 订阅Characteristic的通知
7. 断开连接(disconnect)

 

蓝牙外设模式流程

1. 启动一个Peripheral管理对象
2. 本地Peripheral设置服务,特性,描述,权限等等
3. Peripheral发送广告
4. 设置处理订阅、取消订阅、读characteristic、写characteristic的委托方法

3. Demo(这里只写了中心者模式)

支持蓝牙名称搜索过滤、连接多台蓝牙设备、连续写入多条命令@class LSBluetoothManager;

@protocol LSBluetoothManagerDelegate <NSObject>

@optional
// 获取设备,会调用多次,需要先调用- (void)startScanDevices;
– (void)manager:(LSBluetoothManager *_Nullable)manager didDiscoverDeveice:(nonnull LSBluetoothModel *)peripheral error:(nullable NSError *)error;

// 连接某一台设备是否成功的结果,需要先调用- (void)conect:(CBPeripheral *)peripheral;
– (void)manager:(LSBluetoothManager *_Nonnull)manager connectedDevice:(nonnull CBPeripheral *)peripheral state:(BOOL)state;

// 写入数据结果,需要先调用writeWithPeripheral:(CBPeripheral *_Nonnull)peripheral ServiceUUID:(NSString * _Nonnull )ServiceUUID CharacteristicWriteUUID:(NSString *_Nonnull)characteristicWriteUUID CharacteristicNotifyUUID:(NSString *_Nonnull)characteristicNotifyUUID CMD:(NSString *_Nonnull)CMDString;
– (void)manager:(LSBluetoothManager *_Nullable)manager didUpdateValueForCharacteristic:(nonnull CBCharacteristic *)characteristic receiveData:(NSData *_Nullable)receiveData error:(nullable NSError *)error;

@end

@interface LSBluetoothManager : NSObject

@property (nonatomic, weak, nullable) id <LSBluetoothManagerDelegate> delegate;

// 初始化蓝牙
+ (instancetype _Nonnull )shareManager;

// 蓝牙是否打开,需要设置代理
– (BOOL)isAuthorizationOpen;

// 开始扫描,prefix: 只查找某一个前缀开头的设备,传nil默认扫描所有
– (void)startScanDevicesHasNamePrefix:(NSString *_Nullable)nameprefix;

// 结束扫描
– (void)stopScanDevices;

// 连接某一台设备
– (void)conect:(CBPeripheral *_Nonnull)peripheral ServiceUUID:(NSString * _Nonnull )ServiceUUID CharacteristicWriteUUID:(NSString *_Nonnull)characteristicWriteUUID CharacteristicNotifyUUID:(NSString *_Nonnull)characteristicNotifyUUID;

// 判断获取某一台设备是否在线
– (BOOL)isOnLine:(CBPeripheral *_Nonnull)peripheral ServiceUUID:(NSString *_Nonnull)ServiceUUID;

// 断开某一台设备
– (void)disconect:(CBPeripheral *_Nullable)peripheral;

// 写入数据
– (void)writeWithPeripheral:(CBPeripheral *_Nonnull)peripheral ServiceUUID:(NSString * _Nonnull )ServiceUUID CharacteristicWriteUUID:(NSString *_Nonnull)characteristicWriteUUID CharacteristicNotifyUUID:(NSString *_Nonnull)characteristicNotifyUUID CMD:(NSString *_Nonnull)CMDString;

@end

MAC os 安装 wine

方式一:下载 pkg 安装
https://www.winehq.org/

%title插图%num
安装成功后显示图标

%title插图%num
方式二:命令行用brew
brew search wine

%title插图%num

brew cask install wine-stable

%title插图%num

安装成功,安装过程中会提示输入密码。
接下来就可以直接在终端中使用 wine xxx.exe 。

导出苹果安装包IPA的几种方法

说明一下,这里针对的是没有源码和非越狱设备的几种方法。下面简单介绍下几款软件的用法。

1. Apple Configurator 2
在App Store搜索“Apple Configurator 2”下载安装(*低适配macOS 10.14)
准备工作: Apple ID账号密码, Apple设备。
步骤:

1.1 连接设备到Mac, 菜单 -> 账户 -> 登录

%title插图%num

1.2 添加 -> 应用, 这里会显示你的已购记录,选中应用后添加。这个过程和网速有关,需要等待应用在手机上安装完成。

%title插图%num

如果你已经安装了应用,不要点击任何操作!

1.3 command+shift+G 进入文件夹~/Library/Group Containers/K36BKF7T3D.group.com.apple.configurator/Library/Caches/Assets/TemporaryItems/MobileApps/

%title插图%num

2. 爱思助手(强烈推荐,简直不要太好用了!!!)
准备工作: 无。
不写步骤了,太简单了。连接设备到电脑后下载爱思上的应用到电脑,完成后打开文件夹位置IPA 也就拿到了。

%title插图%num

%title插图%num

3.iMazing
可以把目前手机上自己安装的所有app都导出到电脑上,唯一的缺点就是导出来的格式是imazingapp格式,不是IPA。当然,这种格式也只能用iMazing安装大手机上。
准备工作: Apple设备。
步骤:连接设备后选择应用程序 -> 选中应用 -> 拷贝至MAC -> 保存

%title插图%num

%title插图%num

%title插图%num

4. iTunes
因为iTunes12.6以上版本去掉了应用程序相关功能,所以只能在12.6以下版本的iTunes上进行导出IPA了。具体方法百度一大堆,就不详细说了。如果你很幸运的升级了mac OS ,那么恭喜你中*了,因为想在10.14上装个12.6版本的iTunes我弄了半天都没装好,我太难了,所以有成功的巨佬麻烦告诉一声哈。
下面是iTunes降级安装的相关一些博客帖子,供有兴趣的朋友参考。
https://blog.csdn.net/testcs_dn/article/details/73741822
https://www.jianshu.com/p/225745cae8de
https://blog.csdn.net/SysProgram/article/details/89294694
https://www.v2ex.com/t/393905
https://www.jianshu.com/p/e3457b388829
https://juejin.im/post/5c3c62176fb9a049c965ec01

ps: 以前自己写博客图片都是放在github,今天忽然发现好像不能识别,提示转换失败。这才发现可以直接将本地图片拖拽到编辑器内上传。。。

友情链接: SITEMAP | 旋风加速器官网 | 旋风软件中心 | textarea | 黑洞加速器 | jiaohess | 老王加速器 | 烧饼哥加速器 | 小蓝鸟 | tiktok加速器 | 旋风加速度器 | 旋风加速 | quickq加速器 | 飞驰加速器 | 飞鸟加速器 | 狗急加速器 | hammer加速器 | trafficace | 原子加速器 | 葫芦加速器 | 麦旋风 | 油管加速器 | anycastly | INS加速器 | INS加速器免费版 | 免费vqn加速外网 | 旋风加速器 | 快橙加速器 | 啊哈加速器 | 迷雾通 | 优途加速器 | 海外播 | 坚果加速器 | 海外vqn加速 | 蘑菇加速器 | 毛豆加速器 | 接码平台 | 接码S | 西柚加速器 | 快柠檬加速器 | 黑洞加速 | falemon | 快橙加速器 | anycast加速器 | ibaidu | moneytreeblog | 坚果加速器 | 派币加速器 | 飞鸟加速器 | 毛豆APP | PIKPAK | 安卓vqn免费 | 一元机场加速器 | 一元机场 | 老王加速器 | 黑洞加速器 | 白石山 | 小牛加速器 | 黑洞加速 | 迷雾通官网 | 迷雾通 | 迷雾通加速器 | 十大免费加速神器 | 猎豹加速器 | 蚂蚁加速器 | 坚果加速器 | 黑洞加速 | 银河加速器 | 猎豹加速器 | 海鸥加速器 | 芒果加速器 | 小牛加速器 | 极光加速器 | 黑洞加速 | movabletype中文网 | 猎豹加速器官网 | 烧饼哥加速器官网 | 旋风加速器度器 | 哔咔漫画 | PicACG | 雷霆加速