Learning the Kernel Parameters in Kernel Minimum Distance Abstract Classifier
基于核主成分分析和深度置信网络的暂态稳定评估

基于核主成分分析和深度置信网络的暂态稳定评估#唐文权,徐武,文聪,郭兴(云南民族大学电气信息工程学院,云南昆明650500)摘要:针对电力系统暂态稳定评估实时性较差以及错误率较高的问题,提岀了一种核主成分分析结合深度置信网络的暂态稳定评估方法。
首先,构造了一组电力系统暂态稳定的特征向量;然后,基核主成分分析法对向行提取,向以及余,将的向量传输至深度置信网络;最后,进行训练分析,训程包括预训练和微调,优化网络,提深度置信网络评估精度。
1039系统结 ,该方法可以输的,余,暂态稳定性评估的错误率时间,、电力系统的稳态状态。
关键词:电力系统暂态稳定评估;核主成分分析;特征降维;深度置信网络中图分类号:TM712文献标志码:A文章编号:1673-6540(2021)01-0046-07doi:10.12177/emca.2020.1%5Transient Stability Assessment Based on Kernel Principal ComponentAnalysis and Deep BelieS Network*TANG Wenquan+XU%)WEN Cong,GUO Xing(School of Electrical and Information Technology,Yunnan Minzu University,Kunming650500,China)Abstract:Aiming ai the problems of poos real-time performance and high eiros rate of powcs system transieni stability assessment,a method of transient stability assessment based on kerneC principa-component analysit combined with deep belief network is proposed.Firstly,a set of eigenvectoio reflecting the transient stabOity of power system is constructed.Secondly,the feature vector set is extracted based on kernel principa-component analysis,and the dimensionlity of featura vector is reduced and the redundant features ara filtered.The reduced eicenvectors ara transmitted1w the deep belief network.Finally,training analysis is corried out.The training process includes pretraining and fine tuning t optimize network parameters,and then the evaluation accuacy of deep confidencc network is irnpaved.The sirnulation resultr of NewEngland10-machine39-bus system showthat the method can afective-y aeducethedimenKionayit,oeinputdata,aemoveaedundanteeatuaeK,aeducetheeaoaaateand teKttimeoetaanKient stability assessment,as well as accurate-y and quicky judge the steady state of power system.Key words:power system transiee:stability assessment;kernel principal componeet analysis;featrrr dimensionality reeuction;deep belief network引去复杂性,准确、快速评估电力系统暂态稳定愈发困⑴。
内核调试器kdb代码分析

这是一个很冷门的话题,它受关注的程度永远也比不上陈冠希老师的摄影作品.不过人在江湖身不由己,因为工作原因我不得不接触它,不得不了解一点kdb的代码.Kdb,也叫kernel debugger.是Linux系统的内核调试器,它是一个开源工具,乃是SGI公司开发的.kdb适用于调试内核空间的程序代码,譬如进行设备驱动程序调试,内核模块的调试.Official的Linux kernel并不包含kdb,所以我们必须从sgi的网站上去下载kdb.关于如何安装如何使用kdb,并非本系列文章的重点.实际上,关于kdb的入门,关于kdb的应用,许多年前,当我还在复旦念书的时候,当我才刚学会几个简单的Unix 命令的时候,我就注意到网络上有人发表过这类文章了,所以介绍kdb,推广kdb,并不是我写此文的目的.我所写的是针对kdb本身的分析,针对的是kdb的源代码,或者说kdb的实现.Linux内核每隔一段时间就会发布一个最新的版本,而kdb则会相应的发布与之匹配的补丁.比如你Linux发布了2.6.10的kernel,那么我sgi这边就发布针对2.6.10的kernel的补丁.你发布了2.6.20的kernel,我就发布针对你2.6.20的补丁.比如我之前为了看2.6.22.1的kernel,我就下载了针对2.6.22.1的补丁,或者叫做patch.一共有三个patch:localhost:/usr/src # ls kdb-v4.4-2.6.22-*kdb-v4.4-2.6.22-common-1 kdb-v4.4-2.6.22-i386-1 kdb-v4.4-2.6.22-x86_64-1这三个patch有多长呢:localhost:/usr/src # wc -l kdb-v4.4-2.6.22-*17943 kdb-v4.4-2.6.22-common-114753 kdb-v4.4-2.6.22-i386-114249 kdb-v4.4-2.6.22-x86_64-146945 total我的神,46945行.第一个patch是最基本的patch.第二个patch是针对i386的.第三个patch是针对x86_64的.如果你只对i386感兴趣,那么只关注前两个patch就可以了.首先我们就来看一下这个common的patch.这个patch开门见山的介绍了它对内核中哪些文件进行了修改,或者增加了哪些文件.---Documentation/kdb/kdb.mm | 492 +++++Documentation/kdb/kdb_bp.man | 197 ++Documentation/kdb/kdb_bt.man | 228 ++Documentation/kdb/kdb_env.man | 46Documentation/kdb/kdb_ll.man | 134 +Documentation/kdb/kdb_md.man | 136 +Documentation/kdb/kdb_ps.man | 96Documentation/kdb/kdb_rd.man | 170 +Documentation/kdb/kdb_sr.man | 68Documentation/kdb/kdb_ss.man | 109 +Documentation/kdb/slides | 1382 ++++++++++++++Makefile | 1drivers/char/keyboard.c | 10drivers/hid/usbhid/hid-core.c | 20drivers/hid/usbhid/usbkbd.c | 15drivers/serial/8250.c | 53drivers/serial/8250_early.c | 34drivers/serial/sn_console.c | 73drivers/usb/host/ohci-hcd.c | 47drivers/usb/host/ohci-pci.c | 10drivers/usb/host/ohci-q.c | 62fs/proc/mmu.c | 16fs/proc/proc_misc.c | 114 +include/linux/console.h | 5include/linux/dis-asm.h | 347 +++include/linux/kdb.h | 166 +include/linux/kdbprivate.h | 485 +++++include/linux/sysctl.h | 1init/main.c | 32kdb/ChangeLog | 1672 +++++++++++++++++kdb/Makefile | 28kdb/kdb_bp.c | 619 ++++++kdb/kdb_bt.c | 179 +kdb/kdb_cmds | 32kdb/kdb_id.c | 236 ++kdb/kdb_io.c | 671 ++++++kdb/kdbmain.c | 4034 ++++++++++++++++++++++++++++++++++++++++++kdb/kdbsupport.c | 1134 +++++++++++kdb/modules/Makefile | 14kdb/modules/kdbm_pg.c | 645 ++++++kdb/modules/kdbm_sched.c | 57kdb/modules/kdbm_task.c | 199 ++kdb/modules/kdbm_vm.c | 841 ++++++++kdb/modules/kdbm_x86.c | 1096 +++++++++++kdb/modules/kdbm_xpc.c | 1105 +++++++++++kernel/exit.c | 3kernel/kallsyms.c | 22kernel/module.c | 19kernel/printk.c | 14kernel/sched.c | 79kernel/signal.c | 49mm/hugetlb.c | 19mm/swapfile.c | 2253 files changed, 17330 insertions(+), 8 deletions(-)Kdb一个很突出的特点就是它牵涉的模块倍儿多.很明显,这其中有两个文件可能是我们故事的起点.一个是init/main.c,一个是kdb/kdbmain.c.我们先看这个patch对init/main.c的修改.4909 Index: linux/init/main.c4910 =================================================================== 4911 --- linux.orig/init/main.c4912 +++ linux/init/main.c4913 @@ -66,6 +66,10 @@4914 #include <asm/smp.h>4915 #endif49164917 +#ifdef CONFIG_KDB4918 +#include <linux/kdb.h>4919 +#endif /* CONFIG_KDB */4920 +4921 /*4922 * This is one of the first .c files built. Error out early if we have compiler4923 * trouble.4924 @@ -187,6 +191,26 @@ static const char *panic_later, *panic_p49254926 extern struct obs_kernel_param __setup_start[], __setup_end[];49274928 +#ifdef CONFIG_KDB4929 +static int __init kdb_setup(char *str)4930 +{4931 + if (strcmp(str, "on") == 0) {4932 + kdb_on = 1;4933 + } else if (strcmp(str, "on-nokey") == 0) {4934 + kdb_on = 2;4935 + } else if (strcmp(str, "off") == 0) {4936 + kdb_on = 0;4937 + } else if (strcmp(str, "early") == 0) {4938 + kdb_on = 1;4939 + kdb_flags |= KDB_FLAG_EARLYKDB;4940 + } else4941 + printk("kdb flag %s not recognised/n", str);4942 + return 0;4943 +}4944 +4945 +__setup("kdb=", kdb_setup);4946 +#endif /* CONFIG_KDB */4947 +4948 static int __init obsolete_checksetup(char *line)4949 {4950 struct obs_kernel_param *p;4951 @@ -606,6 +630,14 @@ asmlinkage void __init start_kernel(void4952 pgtable_cache_init();4953 prio_tree_init();4954 anon_vma_init();4955 +4956 +#ifdef CONFIG_KDB4957 + kdb_init();4958 + if (KDB_FLAG(EARLYKDB)) {4959 + KDB_ENTER();4960 + }4961 +#endif /* CONFIG_KDB */4962 +4963 #ifdef CONFIG_X864964 if (efi_enabled)4965 efi_enter_virtual_mode();很明显,增加了两个函数kdb_setup()和kdb_init().kdb_setup()的作用是让你在启动的时候可以传递一个类似于”kdb=on”或者”kdb=off”的内核参数,换言之,它相当于一个开关,给你提供了一种选择,在启动系统的时候你就可以选择打开kdb或者索性关掉kdb.如果你选择了kdb=off,那么就相当于艳照门事件之前陈冠希老师把他的硬盘格式化掉,后面所有的故事都不可能再发生了.来看另一个函数kdb_init(),显然这个函数就是整个kdb的入口,或者说初始化函数.12393 +12394 +/*12395 + * kdb_init12396 + *12397 + * Initialize the kernel debugger environment.12398 + *12399 + * Parameters:12400 + * None.12401 + * Returns:12402 + * None.12403 + * Locking:12404 + * None.12405 + * Remarks:12406 + * None.12407 + */12408 +12409 +void __init12410 +kdb_init(void)12411 +{12412 + kdb_initial_cpu = smp_processor_id();12413 + /*12414 + * This must be called before any calls to kdb_printf.12415 + */12416 + kdb_io_init();12417 +12418 + kdb_inittab(); /* Initialize Command Table */12419 + kdb_initbptab(); /* Initialize Breakpoint Table */12420 + kdb_id_init(); /* Initialize Disassembler */12421 + kdba_init(); /* Architecture Dependent Initialization */12422 +12423 + /*12424 + * Use printk() to get message in log_buf[];12425 + */12426 + printk("kdb version %d.%d%s by Keith Owens, Scott Lurndal. "/12427 + "Copyright SGI, All Rights Reserved/n",12428 + KDB_MAJOR_VERSION, KDB_MINOR_VERSION, KDB_TEST_VERSION);12429 +12430 + kdb_cmd_init(); /* Preset commands from kdb_cmds */12431 + kdb_initial_cpu = -1; /* Avoid recursion problems */12432 + kdb(KDB_REASON_CPU_UP, 0, NULL); /* do kdb setup on boot cpu */12433 + kdb_initial_cpu = smp_processor_id();12434 + atomic_notifier_chain_register(&panic_notifier_list, &kdb_block);12435 + register_cpu_notifier(&kdb_cpu_nfb);12436 +12437 +#ifdef kdba_setjmp12438 + kdbjmpbuf = vmalloc(NR_CPUS * sizeof(*kdbjmpbuf));12439 + if (!kdbjmpbuf)12440 + printk(KERN_ERR "Cannot allocate kdbjmpbuf, no kdb recovery will be possible/n");12441 +#endif /* kdba_setjmp */12442 +12443 + kdb_initial_cpu = -1;12444 + kdb_wait_for_cpus_secs = max(10, 2*num_online_cpus());12445 +}kdb究竟有多复杂,从这个初始化函数就可见一斑.说实话Linux Kernel中光初始化就这么复杂的模块还真的不多.一共五个名字里带”init”的函数.咱们一个一个来看:1.kdb_io_init()8377 +/*8378 + * kdb_io_init8379 + *8380 + * Initialize kernel debugger output environment.8381 + *8382 + * Parameters:8383 + * None.8384 + * Returns:8385 + * None.8386 + * Locking:8387 + * None.8388 + * Remarks:8389 + * Select a console device. Only use a VT console if the user specified8390 + * or defaulted console= /^tty[0-9]*$/8391 + *8392 + * FIXME: 2.6.22-rc1 initializes the serial console long after kdb starts,8393 + * so booting with 'console=tty console=ttyS0' does not create the console8394 + * entry for ttyS0 in time. For now simply assume that we have a working8395 + * console, until a better solution can be found.8396 + */8397 +8398 +void __init8399 +kdb_io_init(void)8400 +{8401 + /*8402 + * Select a console.8403 + */8404 + struct console *c = console_drivers;8405 + int vt_console = 0;8406 +8407 + while (c) {8408 +#if 0 /* FIXME: we don't register serial consoles in time */8409 + if ((c->flags & CON_CONSDEV) && !kdbcons)8410 + kdbcons = c;8411 +#else8412 + if (!kdbcons)8413 + kdbcons = c;8414 +#endif8415 + if ((c->flags & CON_ENABLED) &&8416 + strncmp(c->name, "tty", 3) == 0) {8417 + char *p = c->name + 3;8418 + while (isdigit(*p))8419 + ++p;8420 + if (*p == '/0')8421 + vt_console = 1;8422 + }8423 + c = c->next;8424 + }8425 +8426 + if (kdbcons == NULL) {8427 + printk(KERN_ERR "kdb: Initialization failed - no console. kdb is disabled./n");8428 + KDB_FLAG_SET(NO_CONSOLE);8429 + kdb_on = 0;8430 + }8431 + if (!vt_console)8432 + KDB_FLAG_SET(NO_VT_CONSOLE);8433 + kdb_input_flush();8434 + return;8435 +}所谓的vt_console就是tty0到tty9这些个.console_drivers是一个全局变量,各种各样的console drivers通过调用register_console()来向这个变量注册.比如drivers/serial目录下面各种串口的驱动都有调用这一函数,像8250串口驱动就是注册了一个serial8250_console.kdbcons也是全局变量.它将被赋予console_drivers的第一个console,比如tty0,比如ttyS0.kdb_input_flush()就是延时0.5s.2.kdb_inittab()12212 +/*12213 + * kdb_inittab12214 + *12215 + * This function is called by the kdb_init function to initialize12216 + * the kdb command table. It must be called prior to any other12217 + * call to kdb_register_repeat.12218 + *12219 + * Inputs:12220 + * None.12221 + * Outputs:12222 + * None.12223 + * Returns:12224 + * None.12225 + * Locking:12226 + * None.12227 + * Remarks:12228 + *12229 + */12230 +12231 +static void __init12232 +kdb_inittab(void)12233 +{12234 + int i;12235 + kdbtab_t *kp;12236 +12237 + for(i=0, kp=kdb_commands; i < kdb_max_commands; i++,kp++) {12238 + kp->cmd_name = NULL;12239 + }12240 +12241 + kdb_register_repeat("md", kdb_md, "<vaddr>", "Display Memory Contents, also mdWcN, e.g. md8c1", 1, KDB_REPEAT_NO_ARGS);12242 + kdb_register_repeat("mdr", kdb_md, "<vaddr> <bytes>", "Display Raw Memory", 0, KDB_REPEAT_NO_ARGS);12243 + kdb_register_repeat("mdp", kdb_md, "<paddr> <bytes>", "Display Physical Memory", 0, KDB_REPEAT_NO_ARGS);12244 + kdb_register_repeat("mds", kdb_md, "<vaddr>", "Display Memory Symbolically", 0, KDB_REPEAT_NO_ARGS);12245 + kdb_register_repeat("mm", kdb_mm, "<vaddr> <contents>", "Modify Memory Contents", 0, KDB_REPEAT_NO_ARGS);12246 + kdb_register_repeat("id", kdb_id, "<vaddr>", "Display Instructions", 1, KDB_REPEAT_NO_ARGS);12247 + kdb_register_repeat("go", kdb_go, "[<vaddr>]", "Continue Execution", 1, KDB_REPEAT_NONE);12248 + kdb_register_repeat("rd", kdb_rd, "", "Display Registers", 1, KDB_REPEAT_NONE);12249 + kdb_register_repeat("rm", kdb_rm, "<reg> <contents>", "Modify Registers", 0, KDB_REPEAT_NONE);12250 + kdb_register_repeat("ef", kdb_ef, "<vaddr>", "Display exception frame", 0, KDB_REPEAT_NONE);12251 + kdb_register_repeat("bt", kdb_bt, "[<vaddr>]", "Stack traceback", 1, KDB_REPEAT_NONE);12252 + kdb_register_repeat("btp", kdb_bt, "<pid>", "Display stack for process <pid>", 0, KDB_REPEAT_NONE);12253 + kdb_register_repeat("bta", kdb_bt, "[DRSTCZEUIMA]", "Display stack all processes", 0, KDB_REPEAT_NONE);12254 + kdb_register_repeat("btc", kdb_bt, "", "Backtrace current process on each cpu", 0, KDB_REPEAT_NONE);12255 + kdb_register_repeat("btt", kdb_bt, "<vaddr>", "Backtrace process given its struct task address", 0, KDB_REPEAT_NONE);12256 + kdb_register_repeat("ll", kdb_ll, "<first-element> <linkoffset> <cmd>", "Execute cmd for each element in linked list", 0, KDB_REPEAT_NONE);12257 + kdb_register_repeat("env", kdb_env, "", "Show environment variables", 0, KDB_REPEAT_NONE);12258 + kdb_register_repeat("set", kdb_set, "", "Set environment variables", 0, KDB_REPEAT_NONE);12259 + kdb_register_repeat("help", kdb_help, "", "Display Help Message", 1, KDB_REPEAT_NONE);12260 + kdb_register_repeat("?", kdb_help, "", "Display Help Message", 0, KDB_REPEAT_NONE);12261 + kdb_register_repeat("cpu", kdb_cpu, "<cpunum>","Switch to new cpu", 0, KDB_REPEAT_NONE);12262 + kdb_register_repeat("ps", kdb_ps, "", "Display active task list", 0, KDB_REPEAT_NONE);12263 + kdb_register_repeat("pid", kdb_pid, "<pidnum>", "Switch to another task", 0, KDB_REPEAT_NONE);12264 + kdb_register_repeat("reboot", kdb_reboot, "", "Reboot the machine immediately", 0, KDB_REPEAT_NONE);12265 +#if defined(CONFIG_MODULES)12266 + kdb_register_repeat("lsmod", kdb_lsmod, "", "List loaded kernel modules", 0, KDB_REPEAT_NONE);12267 +#endif12268 +#if defined(CONFIG_MAGIC_SYSRQ)12269 + kdb_register_repeat("sr", kdb_sr, "<key>", "Magic SysRq key", 0, KDB_REPEAT_NONE);12270 +#endif12271 + kdb_register_repeat("dmesg", kdb_dmesg, "[lines]", "Display syslog buffer", 0, KDB_REPEAT_NONE);12272 + kdb_register_repeat("defcmd", kdb_defcmd, "name /"usage/" /"help/"", "Define a set of commands, down to endefcmd", 0, KDB_REPEAT_NONE);12273 + kdb_register_repeat("kill", kdb_kill, "<-signal> <pid>", "Send a signal to a process", 0, KDB_REPEAT_NONE);12274 + kdb_register_repeat("summary", kdb_summary, "", "Summarize the system", 4, KDB_REPEAT_NONE);12275 + kdb_register_repeat("per_cpu", kdb_per_cpu, "", "Display per_cpu variables", 3, KDB_REPEAT_NONE);12276 +}这个函数究竟在干嘛呢?就看见它在不停的调用kdb_register_repeat()函数.如果你使用过kdb,熟悉它的那些个命令,你就会发现,每个命令都在这个函数中出现过,很显然,kdb_register_repeat()不干别的,就为了注册每个命令,kdb_register_repeat()的第二个参数就是与该命令相关的函数,比如dmesg,对应kdb_dmesg,这就意味着一旦你执行dmesg命令,背后真正会被调用的函数就是kdb_dmesg().所有的命令最终被加入到一个全局变量kdb_commands中,这相当于一张表.它默认的大小是50,换言之,你可以定义50个命令,当然你也可以定义更多,有一个变量记录了最大的命令数,这就是kdb_max_commands.8540 + /*8541 + * kdb_commands describes the available commands.8542 + */8543 +static kdbtab_t *kdb_commands;8544 +static int kdb_max_commands;3.kdb_id_init()7724 +/*7725 + * kdb_disinit7726 + *7727 + * Initialize the disassembly information structure7728 + * for the GNU disassembler.7729 + *7730 + * Parameters:7731 + * None.7732 + * Outputs:7733 + * None.7734 + * Returns:7735 + * Zero for success, a kdb diagnostic if failure.7736 + * Locking:7737 + * None.7738 + * Remarks:7739 + */7740 +7741 +void __init7742 +kdb_id_init(void)7743 +{7744 + kdb_di.stream = NULL;7745 + kdb_di.application_data = NULL;7746 + kdb_di.symbols = NULL;7747 + kdb_di.num_symbols = 0;7748 + kdb_di.flags = 0;7749 + kdb_di.private_data = NULL;7750 + kdb_di.buffer = NULL;7751 + kdb_di.buffer_vma = 0;7752 + kdb_di.buffer_length = 0;7753 + kdb_di.bytes_per_line = 0;7754 + kdb_di.bytes_per_chunk = 0;7755 + kdb_di.insn_info_valid = 0;7756 + kdb_di.branch_delay_insns = 0;7757 + kdb_di.data_size = 0;7758 + kdb_di.insn_type = 0;7759 + kdb_di.target = 0;7760 + kdb_di.target2 = 0;7761 +}最没技术含量的一个函数.这其中kdb_di是定义在kdb/kdb_id.c中的一个结构体变量:7544 +disassemble_info kdb_di;一个全局变量.4.kdba_init()kdb后面带个a,a表示arch,说明这个函数是体系结构相关的.换言之,那三个patch中的后两个都会包含这个函数.i386需要它自己的这个函数,x86_64需要属于它的同一个函数.我们来看i386的.8604 +/*8605 + * kdba_init8606 + *8607 + * Architecture specific initialization.8608 + *8609 + * Parameters:8610 + * None.8611 + * Returns:8612 + * None.8613 + * Locking:8614 + * None.8615 + * Remarks:8616 + * None.8617 + */8618 +8619 +void __init8620 +kdba_init(void)8621 +{8622 + kdba_arch_init(); /* Need to register KDBENTER_VECTOR early */8623 + kdb_register("pt_regs", kdba_pt_regs, "address", "Format struct pt_regs", 0);8624 + kdb_register("stackdepth", kdba_stackdepth, "[percentage]", "Print processes using >= stack percentage", 0);8625 +8626 + return;8627 +}这里有包含两个函数.kdba_arch_init().8592 +static int __init8593 +kdba_arch_init(void)8594 +{8595 +#ifdef CONFIG_SMP8596 + set_intr_gate(KDB_VECTOR, kdb_interrupt);8597 +#endif8598 + set_intr_gate(KDBENTER_VECTOR, kdb_call);8599 + return 0;8600 +}原来是设置两个中断门.这里涉及了两个中断向量.KDB_VECTOR和KDBENTER_VECTOR.与之想绑定的分别是两个函数,kdb_interrupt和kdb_call.而kdb_register()其实就是kdb_register_repeat()的另一版本.等于说这里又注册了pt_regs和stackdepth这两个命令.12139 +/*12140 + * kdb_register12141 + *12142 + * Compatibility register function for commands that do not need to12143 + * specify a repeat state. Equivalent to kdb_register_repeat with12144 + * KDB_REPEAT_NONE.12145 + *12146 + * Inputs:12147 + * cmd Command name12148 + * func Function to execute the command12149 + * usage A simple usage string showing arguments12150 + * help A simple help string describing command12151 + * Outputs:12152 + * None.12153 + * Returns:12154 + * zero for success, one if a duplicate command.12155 + * Locking:12156 + * none.12157 + * Remarks:12158 + *12159 + */12160 +12161 +int12162 +kdb_register(char *cmd,12163 + kdb_func_t func,12164 + char *usage,12165 + char *help,12166 + short minlen)12167 +{12168 + return kdb_register_repeat(cmd, func, usage, help, minlen, KDB_REPEAT_NONE);12169 +}Linux内核中像这种注册或者说登记的函数到处都是,从本质上来说,无非就是有一张表,然后同一类型的变量或者数据或者函数或者指针都登记到这张表里去,便于统一管理.这种思想应用到现实中来,就好比北京市公安局打着迎奥运的名义,要求外来人口去办暂住证一样,都办了暂住证,为奥运操心的公仆们就能很好的管理我们这些刁民,贱民和草民了.5.kdb_cmd_init()12278 +/*12279 + * kdb_cmd_init12280 + *12281 + * This function is called by the kdb_init function to execute any12282 + * commands defined in kdb_cmds.12283 + *12284 + * Inputs:12285 + * Commands in *kdb_cmds[];12286 + * Outputs:12287 + * None.12288 + * Returns:12289 + * None.12290 + * Locking:12291 + * None.12292 + * Remarks:12293 + *12294 + */12295 +12296 +static void __init12297 +kdb_cmd_init(void)12298 +{12299 + int i, diag;12300 + for (i = 0; kdb_cmds[i]; ++i) {12301 + if (!defcmd_in_progress)12302 + kdb_printf("kdb_cmd[%d]: %s", i, kdb_cmds[i]);12303 + diag = kdb_parse(kdb_cmds[i]);12304 + if (diag)12305 + kdb_printf("command failed, kdb diag %d/n", diag);12306 + }12307 + if (defcmd_in_progress) {12308 + kdb_printf("Incomplete 'defcmd' set, forcing endefcmd/n");12309 + kdb_parse("endefcmd");12310 + }12311 +}这又是初始化什么呢?kdb_cmds是一个数组.所有的命令都被添加到这里.35 extern char *kdb_cmds[]; char __initdata *kdb_cmds[]它有许许多多个成员,每一个成员表示一条命令,当然你也可以说每一个成员表示一个字符串.defcmd_in_progress是一个全局变量,默认当然是0.而kdb_parse()将解析这个命令,如果这个命令能够在kdb_commands这张表里面找到,那么与这个命令相关的函数将会执行.比如说你执行dmesg命令,那么kdb_dmesg()函数就会被调用.初始化基本上要好了,咱们调用kdb()函数.这个函数是kdb中最核心的函数之一.这个函数我们以后会有大把的机会和它打交道.这里由于传递进来的参数比较特别,实际上它不会做什么事情.紧接着, atomic_notifier_chain_register是注册一个notifier chain.kdb_block.notifier chain是一种通知机制,我们不去深究它,事实上要深究也没问题,网上关于notifier chain的文章也不少.这里我们只想说,我们通过这行代码实际上绑定了一个kdb_panic()函数,在系统崩溃的时候,这个函数会被调用,从而进入kdb.kdb_panic以及kdb_block的定义都在下面:12313 +/*12314 + * kdb_panic12315 + *12316 + * Invoked via the panic_notifier_list.12317 + *12318 + * Inputs:12319 + * None.12320 + * Outputs:12321 + * None.12322 + * Returns:12323 + * Zero.12324 + * Locking:12325 + * None.12326 + * Remarks:12327 + * When this function is called from panic(), the other cpus have already12328 + * been stopped.12329 + *12330 + */12331 +12332 +static int12333 +kdb_panic(struct notifier_block *self, unsigned long command, void *ptr)12334 +{12335 + KDB_FLAG_SET(CATASTROPHIC); /* kernel state is dubious now */12336 + KDB_ENTER();12337 + return 0;12338 +}12339 +12340 +static struct notifier_block kdb_block = { kdb_panic, NULL, 0 };以后我们会看到KDB_ENTER()这个宏将引领我们进入kdb.只是此刻我想,kernel崩溃了,可以进入kdb,看代码的我崩溃了,找谁去?再然后是register_cpu_notifier,这又是注册啥呢?暂时不得而知.接下来,kdbjmpbuf,很明显,这是一个setjmp buffer,用于异常处理.setjmp和longjmp通常组合起来用,前者用于保存程序的运行时的堆栈环境,后者则用来恢复先前保存的程序堆栈环境.这二者一起使用就能提供传说中那种在程序中实现非本地跳转的机制(non-local goto).关于setjmp和longjmp,网上相关的文章那是比阿娇的艳照还要多,这里就不多说了.(当然,阿娇的照片之所以少,主要是警察叔叔有功!)与kdbjmpbuf相对应的setjmp函数我们以后会看到,叫做kdba_setjmp(),与之相对应的longjmp函数则叫做kdba_longjmp.简而言之,我们会先调用kdba_setjmp()来初始化kdbjmpbuf,或者说将CPU中大部分影响到程序执行的寄存器存入kdbjmpbuf,而日后等我们使用kdba_longjmp()函数之后,能够使程序再次跳转会kdba_setjmp()的位置.需要多说一句,从这里的申请内存时使用的NR_CPUS我们知道,这个buffer实际上是为每个CPU都准备了一个.最后,kdb_initial_cpu设置为-1.kdb_wait_for_cpus_secs也赋了一个值,如果你是单cpu那么这个变量就被设置为10.你可以用kdb察看一下.比如下面我的机器里看到的那样:kdb> md kdb_wait_for_cpus_secs0xffffffff8062db18 000000000000000a 0000000000000000 ................0xffffffff8062db28 0000000000000000 0000000000000000 ................0xffffffff8062db38-0xffffffff8062db87 zero suppressed0xffffffff8062db88 0000000000000000 0000000000000000 ................0a当然就是10.这样,kdb的初始化就算是完成了.Linux中有些模块,你看明白它怎么初始化的你基本上就能明白它是怎么工作了,比如usb-storage,以及usb hub driver,但有些模块就没有这么简单了,就比如uhci/ehci,就比如kdb.初始化完了之后故事才刚刚拉开帷幕,如果拿近期百家讲坛热播的纪连海老师讲的李连英的故事对比,那么现在也就相当于李连英公公刚刚进宫,刚刚开始他那伟大的太监生涯.像usb-storage那样的模块,你可以很清楚它的结构,从哪里开始到哪里结束,整个就是一条直线.而kdb就不一样了,它初始化完成了之后,就将准备应对多种情况了,比如你进入kdb,这就有多种情形,你可以直接调用相关的宏进入kdb,也可以设置断点来进入kdb,你可以按pause键进入kdb,也可以在serial console上按ctrl-a进入kdb,还可能是系统崩溃了自动进入kdb.总而言之有诸多的可能,所以就要有相应的代码来应付.下面我们首先就先来看一下,从串行终端上按了ctrl-a之后,为什么就可以进入kdb.很明显,这里牵涉到了serial console的驱动,更准确地说其实是Intel 8250串口芯片驱动.虽然串口芯片很多,但是Intel 8250无疑是最有名的,大多数服务器上的串口都是8250芯片.kdb-v4.4-2.6.22-common-1这个patch中说了,以下四个文件是作了修改的.17 drivers/serial/8250.c | 5318 drivers/serial/8250_early.c | 3419 drivers/serial/sn_console.c | 7325 include/linux/console.h | 5很长一段时间我一直困惑,计算机怎么知道我按了”control-a”呢,后来才明白,键盘上的control-a实际上对应的是ASCII码中的001.(control-b对应002,control-c对应003,…另外,control-@对应000)所以从键盘驱动来说,它就把这个组合键当作一个字符来处理.而kdb的patch在drivers/serial/8250.c中加了这么一段:3295 Index: linux/drivers/serial/8250.c3296 =================================================================== 3297 --- linux.orig/drivers/serial/8250.c3298 +++ linux/drivers/serial/8250.c3299 @@ -45,6 +45,19 @@3300 #include <asm/irq.h>33013302 #include "8250.h"3303 +#include <linux/kdb.h>3304 +#ifdef CONFIG_KDB3305 +/*3306 + * kdb_serial_line records the serial line number of the first serial console.3307 + * NOTE: The kernel ignores characters on the serial line unless a user space3308 + * program has opened the line first. To enter kdb before user space has opened3309 + * the serial line, you can use the 'kdb=early' flag to lilo and set the3310 + * appropriate breakpoints.3311 + */3312 +3313 +static int kdb_serial_line = -1;3314 +static const char *kdb_serial_ptr = kdb_serial_str;3315 +#endif /* CONFIG_KDB */33163317 /*3318 * Configuration:3319 @@ -1287,6 +1300,20 @@ receive_chars(struct uart_8250_port *up,33203321 do {3322 ch = serial_inp(up, UART_RX);3323 +#ifdef CONFIG_KDB3324 + if ((up->port.line == kdb_serial_line) && kdb_on == 1) {3325 + if (ch == *kdb_serial_ptr) {3326 + if (!(*++kdb_serial_ptr)) {3327 + atomic_inc(&kdb_8250);3328 + kdb(KDB_REASON_KEYBOARD, 0, get_irq_regs());3329 + atomic_dec(&kdb_8250);3330 + kdb_serial_ptr = kdb_serial_str;3331 + break;3332 + }3333 + } else3334 + kdb_serial_ptr = kdb_serial_str;3335 + }3336 +#endif /* CONFIG_KDB */3337 flag = TTY_NORMAL;3338 up->port.icount.rx++;3339这里的kdb_serial_str其实就是control-a,或者说用ascii码的形式表示为”/001”.这里的receive_char很明显,就是串行终端接收字符时调用的函数.ch就是接收到的字符,如果它是control-a,那么3328添加的代码就会执行,换言之,kdb()函数会被调用.不过这里我们需要注意的是,当我还是青春期的时候,当我还在看琼瑶剧的时候,当我还迷恋快乐大本营的时候,人们要从串行终端进入kdb得按control-a键,但后来人们发现control-a进入不了kdb了,要进入kdb得按另外的键,这就是escape键后接KDB.关于这一点,原因是kdb_serial_str这个字符串经过了修改,曾几何时,它是被定义为/001,但现在你会发现,这个字符串被定义为”/eKDB”,”/e”实际上对应你敲击的键盘就是escape键.关于这个字符串的定义,我们可以从patch里面找到:8639 +/*8640 + * kdb_serial_str is the sequence that the user must enter on a serial8641 + * console to invoke kdb. It can be a single character such as "/001"8642 + * (control-A) or multiple characters such as "/eKDB". NOTE: All except the8643 + * last character are passed through to the application reading from the serial8644 + * console.8645 + *8646 + * I tried to make the sequence a CONFIG_ option but most of CML1 cannot cope8647 + * with '/' in strings. CML2 would have been able to do it but we lost CML2.8648 + * KAO.8649 + */8650 +const char kdb_serial_str[] = "/eKDB";8651 +EXPORT_SYMBOL(kdb_serial_str);所以结合上面的代码来看,kdb_serial_str表示一个const的字符串,而kdb_serial_ptr则是一个char型指针,指针开始指向kdb_serial_str,然后不停的游荡,每次串行终端上有输入,换言之,ch有值,就拿它和kdb_serial_ptr所指向的字符相比较,如果相同就令kdb_serial_ptr指向下一个字符,然后接着如果你继续输入,就继续比较,直到比较完了以后发现,你输入的恰恰就是<escape>KDB,那么调用kdb(),从而进入kdb.下面是效果图:(在串行终端上K和B都没有回显出来,只有D回显了.)[root@localhost ~]# DEntering kdb (current=0xffffffff805563a0, pid 0) due to Keyboard Entrykdb>不过像我这种习惯了按control-a进kdb的人,一般会把这里/eKDB手工改为/001.知道了serial console这边是如何进入kdb的,我们再来看本地键盘,在这里只要你按Pause键就可以进入kdb,这又是为什么呢?看人家的patch改了什么:3182 Index: linux/drivers/char/keyboard.c3183 =================================================================== 3184 --- linux.orig/drivers/char/keyboard.c3185 +++ linux/drivers/char/keyboard.c3186 @@ -40,6 +40,9 @@3187 #include <linux/sysrq.h>3188 #include <linux/input.h>3189 #include <linux/reboot.h>3190 +#ifdef CONFIG_KDB3191 +#include <linux/kdb.h>3192 +#endif /* CONFIG_KDB */31933194 extern void ctrl_alt_del(void);31953196 @@ -1138,6 +1141,13 @@ static void kbd_keycode(unsigned int key3197 if (keycode < BTN_MISC && printk_ratelimit())3198 printk(KERN_WARNING "keyboard.c: can't emulate rawmode for keycode %d/n", keycode);31993200 +#ifdef CONFIG_KDB3201 + if (down && !rep && keycode == KEY_PAUSE && kdb_on == 1) {3202 + kdb(KDB_REASON_KEYBOARD, 0, get_irq_regs());3203 + return;3204 + }3205 +#endif /* CONFIG_KDB */3206 +3207 #ifdef CONFIG_MAGIC_SYSRQ /* Handle the SysRq Hack */3208 if (keycode == KEY_SYSRQ && (sysrq_down || (down == 1 && sysrq_alt))) {3209 if (!sysrq_down) {很显然,就是修改drivers/char/keyboard.c,这就是键盘驱动,我们看到会比较keycode与KEY_PAUSE,如果相同,就说明你输入的是pause键,于是3202行这里我们看到kdb()再一次被调用.这样我们就明白了为什么从串行终端按control-a以及从本地键盘按pause键会触发kdb了.但这些方式都太直接了,而且是你主动要进kdb,颇有一种纸上谈兵的味道.须知有的时候,进入kdb并不是你主观上期望的,往往是系统崩溃的时候自动进入的,这又是怎么回事儿呢?来看一个关键的函数,来自kernel/panic.c:60 NORET_TYPE void panic(const char * fmt, ...)61 {62 long i;63 static char buf[1024];64 va_list args;65 #if defined(CONFIG_S390)66 unsigned long caller = (unsigned long) __builtin_return_address(0);67 #endif6869 /*70 * It's possible to come here directly from a panic-assertion and not71 * have preempt disabled. Some functions called from here want72 * preempt to be disabled. No point enabling it later though...73 */74 preempt_disable();7576 bust_spinlocks(1);77 va_start(args, fmt);78 vsnprintf(buf, sizeof(buf), fmt, args);79 va_end(args);80 printk(KERN_EMERG "Kernel panic - not syncing: %s/n",buf);81 bust_spinlocks(0);8283 /*84 * If we have crashed and we have a crash kernel loaded let it handle85 * everything else.86 * Do we want to call this before we try to display a message?87 */88 crash_kexec(NULL);8990 #ifdef CONFIG_SMP91 /*92 * Note smp_send_stop is the usual smp shutdown function, which93 * unfortunately means it may not be hardened to work in a panic94 * situation.95 */96 smp_send_stop();97 #endif9899 atomic_notifier_call_chain(&panic_notifier_list, 0, buf);100101 if (!panic_blink)102 panic_blink = no_blink;103104 if (panic_timeout > 0) {105 /*106 * Delay timeout seconds before rebooting the machine.107 * We can't use the "normal" timers since we just panicked..108 */109 printk(KERN_EMERG "Rebooting in %d seconds..",panic_timeout);110 for (i = 0; i < panic_timeout*1000; ) {111 touch_nmi_watchdog();112 i += panic_blink(i);113 mdelay(1);114 i++;115 }116 /* This will not be a clean reboot, with everything117 * shutting down. But if there is a chance of118 * rebooting the system it will be rebooted.119 */120 emergency_restart();121 }122 #ifdef __sparc__。
Linux Kernel Coding Style

a g e1ContentsLinux Kernel Coding Style (Linux 内核代码风格) (2)Chapter 1: Indentation (缩进) ............................................................................................ 2 Chapter 2: Breaking long lines and strings (把长的行和字符串打散) ..................................... 4 Chapter 3: Placing Braces (大括号和空格的放置) ............................................................ 4 3.1 Spaces (空格) ................................................................................................................ 6 Chapter 4: Naming (命名) .................................................................................................. 8 Chapter 5: Typedefs .................................................................................................................. 9 Chapter 6: Functions (函数) ............................................................................................. 11 Chapter 7: Centralized exiting of functions (集中的函数退出途径) ...................................... 12 Chapter 8: Commenting (注释) ............................................................................................... 13 Chapter 9: You've made a mess of it (你已经把事情弄糟了) ................................................ 15 Chapter 10: Kconfig configuration files (Kconfig 配置文件) ................................................ 16 Chapter 11: Data structures (数据结构) ................................................................................. 17 Chapter 12: Macros, Enums and RTL (宏,枚举和RTL ) .................................................. 18 Chapter 13: Printing kernel messages (打印内核消息) .......................................................... 19 Chapter 14: Allocating memory (分配内存) ........................................................................... 20 Chapter 15: The inline disease (内联弊病) ............................................................................. 21 Chapter 16: Function return values and names (函数返回值及命名) ................................... 22 Chapter 17: Don't re-invent the kernel macros (不要重新发明内核宏) ............................... 23 Chapter 18: Editor modelines and other cruft (编辑器模式行和其他需要罗嗦的事情) ..... 24 Appendix I: References .. (24)a g e2Linux Kernel Coding Style (Linux 内核代码风格)This is a short document describing the preferred coding style for the linux kernel. Coding style is very personal, and I won't _force_ my views on anybody, but this is what goes for anything that I have to be able to maintain, and I'd prefer it for most other things too. Please at least consider the points made here.这是一个简短的文档,描述了linux 内核的首选代码风格。
用户空间和内核空间通讯之【Netlink下】

用户空间和内核空间通讯之【Netlink下】在上一篇博文中我们所遇到的情况都是用户空间作为消息进程的发起者,Netlink还支持内核作为消息的发送方的情况。
这一般用于内核主动向用户空间报告一些内核状态,例如我们在用户空间看到的USB的热插拔事件的通告就是这样的应用。
先说一下我们的目标,内核线程每个一秒钟往一个多播组里发送一条消息,然后用户空间所以加入了该组的进程都会收到这样的消息,并将消息内容打印出来。
Netlink地址结构体中的nl_groups是32位,也就是说每种Netlink协议最多支持32个多播组。
如何理解这里所说的每种Netlink 协议?在</usr/include/linux/netlink.h>里预定义的如下协议都是Netlink协议簇的具体协议,还有我们添加的NETLINK_TEST也是一种Netlink协议。
1.#define NETLINK_ROUTE 0 /*Routing/device hook */2.#define NETLINK_UNUSED 1 /*Unused number */3.#define NETLINK_USERSOCK 2 /*Reserved for user mode socket protocols */4.#define NETLINK_FIREWALL 3 /*Firewalling hook */5.#define NETLINK_INET_DIAG 4 /*INET socket monitoring */6.#define NETLINK_NFLOG 5 /*netfilter/iptables ULOG */7.#define NETLINK_XFRM 6 /* ipsec */8.#define NETLINK_SELINUX 7 /*SELinux event notifications */9.#define NETLINK_ISCSI 8 /* Open-iSCSI */10.#define NETLINK_AUDIT 9 /* auditing */11.#define NETLINK_FIB_LOOKUP 1012.#define NETLINK_CONNECTOR 1113.#define NETLINK_NETFILTER 12 /*netfilter subsystem */14.#define NETLINK_IP6_FW 1315.#define NETLINK_DNRTMSG 14 /*DECnet routing messages */16.#define NETLINK_KOBJECT_UEVENT 15 /*Kernel messages to userspace */17.#define NETLINK_GENERIC 1618./* leave room for NETLINK_DM (DM Events)*/19.#define NETLINK_SCSITRANSPORT 18 /*SCSI Transports */20.#define NETLINK_ECRYPTFS 1921.#define NETLINK_TEST 20 /* 用户添加的自定义协议 */在我们自己添加的NETLINK_TEST协议里,同样地,最多允许我们设置32个多播组,每个多播组用1个比特表示,所以不同的多播组不可能出现重复。
融合注意力和门控空洞卷积的关系识别模型python代码

融合注意力和门控空洞卷积的关系识别模型python代码全文共四篇示例,供读者参考第一篇示例:在深度学习领域,注意力机制和门控卷积是两个被广泛应用的技术。
注意力机制能够帮助模型集中关注于重要的特征,从而提高模型的性能。
而门控卷积则能够有效地捕捉序列数据中的长距离依赖关系。
在本文中,我们将探讨如何将注意力机制和门控卷积结合起来,构建一个用于关系识别的深度学习模型,并使用Python代码实现。
我们需要了解注意力机制和门控卷积的基本原理。
注意力机制是一种用于给予模型不同输入部分不同权重的技术,帮助模型更聚焦于重要的特征。
门控卷积则是一种包含门控单元(如LSTM或GRU)的卷积层,能够在卷积的基础上引入序列建模的能力,捕捉长距离的依赖关系。
接下来,我们将介绍如何将注意力机制和门控卷积结合起来,构建一个关系识别模型。
我们将使用Python编写代码,使用PyTorch作为深度学习框架。
我们需要导入必要的库和模块:```pythonimport torchimport torch.nn as nnimport torch.nn.functional as F```接着,我们定义一个包含注意力机制和门控卷积的关系识别模型:```pythonclass RelationRecognitionModel(nn.Module):def __init__(self, input_dim, hidden_dim, output_dim, num_layers):super(RelationRecognitionModel, self).__init__()self.hidden_dim = hidden_dimself.num_layers = num_layers# 定义门控卷积层self.conv = nn.Conv1d(input_dim, hidden_dim, kernel_size=3, padding=1)# 定义注意力机制self.attention = nn.Linear(hidden_dim, 1)# 定义LSTM层self.lstm = nn.LSTM(hidden_dim, hidden_dim, num_layers, batch_first=True)# 定义输出层self.fc = nn.Linear(hidden_dim, output_dim)def forward(self, x):# 进行卷积操作x = F.relu(self.conv(x))# 计算注意力权重attention_weights = F.softmax(self.attention(x), dim=1)# 将注意力权重应用到卷积结果上x = x * attention_weights# 将数据输入到LSTM层h0 = torch.zeros(self.num_layers, x.size(0),self.hidden_dim).to(x.device)c0 = torch.zeros(self.num_layers, x.size(0),self.hidden_dim).to(x.device)out, _ = self.lstm(x, (h0, c0))# 获取LSTM输出的最后一个时间步的结果,并输入到全连接层out = self.fc(out[:, -1, :])return out```在上面的代码中,我们首先定义了一个包含门控卷积、注意力机制、LSTM和全连接层的关系识别模型。
initramfs

狗拿耗子initramfs———狗拿耗子第十八篇 《understanding the linux kernel》在讲解 VFS 的时候,介绍了 rootfs 的 mount 过 程,首先是 mount 一个简单的 rootfs,然后再在某个块设备上 mount 上真正的 rootfs。
而 采用 initramfs 机制,只需要一次 mount,就可以建立起 rootfs。
内核从无到有准备好 process 0 后,由 process 0 创建 process 1,而 process 1 继续 进行初始化工作,最终运行 rootfs 下面的 init 可执行脚本。
所以 initramfs 除了准备好 mount rootfs 需要的东东,还需要准备好内核需要 rootfs 包含的可执行程序与脚本。
接下 来,我们来看看 initramfs 到底是怎么工作的。
硬件环境仍然是那块 smdk_2410 的板子,这次是在板子上运行,而不是在 skyeye 上仿 真了。
u-boot 版本为 2010.03,linux 版本为 2.6.35.5,busybox 版本为 1.17.2,编译工具 为 eldk-2008.11.24。
1、initramfs 压缩包文件 initramfs 压缩包文件指的是, 将某个目录经过打包与压缩后得到的文件, 该目录按 rootfs 的要求存放有, 可执行文件与配置文件, 下面简称为 initramfs 包。
所使用的打包程序为 cpio, 压缩程序为 gzip。
1.1 initramfs 包的内容 《building embedded linux systems》里面详细讨论了 rootfs 需要包含的东东,有内 核需要的共享库、驱动模块、设备文件、系统工具以及配置文件。
静态编译内核,则不需要 共享库。
静态编译驱动程序,则不需要驱动模块。
通过 busybox 动态生成设备文件,则不需 要在 rootfs 提前准备好设备文件。
Kernel panic常见原因

kernel panic错误表现kernel panic 主要有以下几个出错提示:Kernel panic-not syncing fatal exception in interruptkernel panic - not syncing: Attempted to kill the idle task!kernel panic - not syncing: killing interrupt handler!Kernel Panic - not syncing:Attempted to kill init !kernel错误分析查看了一下 linux的源码文件,找到相关位置kernel/panic.cNORET_TYPE void panic(const char * fmt, ...){static char buf[1024];va_list args;bust_spinlocks(1);va_start(args, fmt);vsnprintf(buf, sizeof(buf), fmt, args);va_end(args);printk(KERN_EMERG "Kernel panic - not syncing: %s/n",buf);bust_spinlocks(0);kernel/exit.cif (unlikely(in_interrupt()))panic("Aiee, killing interrupt handler!"); #中断处理if (unlikely(!tsk->pid))panic("Attempted to kill the idle task!"); #空任务if (unlikely(tsk->pid == 1))panic("Attempted to kill init!"); #初始化从其他源文件和相关文档看到应该有几种原因:1、硬件问题使用了 SCSI-device 并且使用了未知命令#WDIOS_TEMPPANIC Kernel panic on temperature trip## The SETOPTIONS call can be used to enable and disable the card# and to ask the driver to call panic if the system overheats.## If one uses a SCSI-device of unsupported type/commands, one# immediately runs into a kernel-panic caused by Command Error. To better # understand which SCSI-command caused the problem, I extended this# specific panic-message slightly.##read/write causes a command error from# the subsystem and this causes kernel-panic2、系统过热如果系统过热会调用panci,系统挂起#WDIOS_TEMPPANIC Kernel panic on temperature trip## The SETOPTIONS call can be used to enable and disable the card# and to ask the driver to call panic if the system overheats.3、文件系统引起#A variety of panics and hangs with /tmp on a reiserfs filesystem#Any other panic, hang, or strange behavior## It turns out that there's a limit of six environment variables on the# kernel command line. When that limit is reached or exceeded, argument # processing stops, which means that the 'root=' argument that UML# usually adds is not seen. So, the filesystem has no idea what the# root device is, so it panics.# The fix is to put less stuff on the command line. Glomming all your# setup variables into one is probably the best way to go.Linux内核命令行有6个环境变量。
linux printk日志级别

linux printk日志级别“linux printk日志级别”的文章一、引言在Linux系统中,打印日志是一种常见的调试和错误排查的方式,而打印日志的级别则是很重要的一项功能。
本文将深入探讨Linux中的printk日志级别,解释各个级别的含义,并介绍如何使用和调整这些日志级别。
二、什么是printk日志级别printk是Linux内核中的一个打印函数,用于在系统运行过程中输出日志信息,帮助开发人员进行调试和错误排查。
而日志级别则是控制打印日志信息的重要因素,通过设置不同的日志级别,可以选择性地输出不同程度和类型的日志信息。
三、printk日志级别的分类在Linux中,printk日志级别被划分为不同的等级,包括8个级别,从最高到最低分别是:KERN_EMERG(紧急)、KERN_ALERT(警报)、KERN_CRIT(严重)、KERN_ERR(错误)、KERN_WARNING(警告)、KERN_NOTICE(通知)、KERN_INFO(信息)和KERN_DEBUG(调试)。
1. KERN_EMERG(紧急):表示系统出现严重的问题,必须立即采取措施进行修复,否则可能导致系统崩溃或数据损坏。
2. KERN_ALERT(警报):表示系统出现了一些严重的问题,需要立即关注和处理,但不会导致系统崩溃。
3. KERN_CRIT(严重):表示系统出现了一些严重的问题,需要尽快处理,但不会影响系统的正常运行。
4. KERN_ERR(错误):表示系统出现了一些错误,可能导致某些功能无法正常工作,但系统仍然能继续运行。
5. KERN_WARNING(警告):表示系统出现了一些警告信息,可能暗示一些潜在问题,但不会对系统造成实质性影响。
6. KERN_NOTICE(通知):表示系统的某些事件或状态发生变化,通知管理员或开发人员关注。
7. KERN_INFO(信息):表示系统输出一些普通的日志信息,用于查看系统的运行情况。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Learning the Kernel Parameters in Kernel Minimum DistanceClassifierDaoqiang Zhang1,2, Songcan Chen2 and Zhi-Hua Zhou1*1 National Laboratory for Novel Software TechnologyNanjing University, Nanjing 210093, China2 Department of Computer Science and EngineeringNanjing University of Aeronautics and Astronautics, Nanjing 210016, China AbstractChoosing appropriate values for kernel parameters is one of the key problems in many kernel-based methods because the values of these parameters have significant impact on the performances of these methods. In this paper, a novel approach is proposed to learn the kernel parameters in kernel minimum distance (KMD) classifier, where the values of the kernel parameters are computed through optimizing an objective function designed for measuring the classification reliability of KMD. Experiments on both artificial and real-world datasets show that the proposed approach works well on learning kernel parameters of KMD.Keywords: Kernel minimum distance; kernel parameter optimization; kernel selection1. IntroductionMinimum distance (MD) and nearest neighbor (NN) are simple but popular techniques in pattern recognition. Recently, both methods have been extended to kernel versions, i.e. the kernel minimum distance (KMD) and kernel nearest neighbor (KNN), for classifying complex and nonlinear patterns such as faces [1], [2]. However, like other kernel-based methods, the performance of KMD and KNN is greatly affected by the selection of kernel parameters values. In this paper, we focus on optimizing the kernel parameters for KMD.In the literature, there are two widely used approaches in choosing the values of kernel parameters in kernel-based methods [1], [3], [4]. The first approach empirically chooses a series of candidate values for the kernel parameter, executes the concerned method under these values again* Corresponding author. Email: zhouzh@, Tel.: +86-25-8368-6268, Fax: +86-25-8368-6268and again, and selects the one corresponding to the best performance as the final kernel parameter value. However, this approach suffers from the fact that only a very limited candidate values are considered, therefore the performance of the kernel-based methods may not be optimized. The second approach is the well-known cross-validation, which is also widely used in model selection. Compared with the first approach, cross-validation often yields better performance because it searches the optimal value for kernel parameter in a much wider range. However, performing cross-validation is often time-consuming and hence it cannot be used to adjust the kernel parameters in real time [3]. Furthermore, when there are only a limited number of training examples, the cross-validation approach can hardly ensure robust estimation.In this paper, a novel approach is proposed to learn the kernel parameters in KMD. At first an objective function is defined to measure the classification reliability of KMD with different kernel parameters. Then, the optimal values of the kernel parameters are chosen through optimizing the above defined objective function. Experiments on both artificial and real-world datasets show the effect of the proposed approach on learning kernel parameters in KMD.2. Kernel minimum distance classifierOne of the key ingredients of KMD is the definition of kernel-induced distance measures. Given a data set {}1,...,l S x x = sampled from the input space X , a kernel K (x ,y ) and a function Φin a feature space satisfy K (x ,y ) = Φ(x )T Φ(y ). An important property of the kernel is that it can be directly constructed in the original input space without knowing the concrete form of Φ. That is, a kernel implicitly defines a nonlinear mapping function. There are several typical kernels, e.g. the Gaussian kernel 22||||(,)exp 2x y K x y σ⎛−=⎜⎝⎠⎞⎟d , the polynomial kernel (,)(1)T K x y x y =+, etc. The kernel-induced distance between two points defined by a kernel K is shown in Eq. (1).22(,)||()()||(,)2(,)(,)d x y x y K x x K x y K y y =Φ−Φ=−+. (1)Suppose the training data set S contains c different classes, i.e., and eachclass has samples, satisfying 12,,...,c S S S i S i l 1ci i l l ==∑. Let {}()()|i j j i S x x Φ=Φ∈S be the image of classunder the map Φ, and denote the centre of i S ()i S Φ as1()i j i S x S i j x l ∈Φ=Φ∑. (2)Then, the distance between the image of a new point x and the centre of class can be computed asi S Φ222,((),)||()|| ()()2()12 (,)(,)(,)i i i i i j k i j iS S T TT S S S j k j x x S x S i i d x x x x x K x x K x x K x x l l ∈∈ΦΦ=Φ−Φ=ΦΦ+ΦΦ−ΦΦ=+−∑∑ (3)According to Eq. (3), the classification rule in KMD is to assign the new point x to the class with the smallest distance:{}21()arg min ((),)i S i c h x d x ≤≤=ΦΦ (4)3. The proposed methodThe following objective function is defined to measure the classification reliability of KMD with different kernel parameters:()()2211()((),)()exp min ((),)i j l i S i i S j c j i d x J d x ππθ=≤≤≠⎛⎞⎜⎟ΦΦ⎜=⎜⎟ΦΦ⎜⎟⎝⎠∑⎟ (5)Here θ denotes the kernel parameters, and ()i πdenotes the class label of i x . The intuitionbehind Eq. (5) is to make the distance between the image of a sample and the centre of its corresponding class as small as possible, while to make the distance between the image of the sample to other classes as large as possible. The smaller the value of the objective function, the higher the classification reliability. Here the exponential function is used for speeding up the convergence of optimization.Note that when ()()221()((),)min ((),)i i S i S j c j i d x d x ππ≤≤≠ΦΦ<ΦΦj , the sample i x is correctly classified. Equation (5) specifies that the optimal value for a kernel parameter should not only correctly classify the training data, but also make the classification reliability as high as possible. In the extreme case where and ()2((),)0i i S d x πΦΦ=()21()min ((),)j i S j c j i d x π≤≤≠ΦΦ=∞ for each i x , the highest classification reliability is obtained.The optimal values of the kernel parameters can be obtained through minimizing Eq. (5), i.e.*arg min ()J θθθ=. (6)In this paper, an iterative algorithm is employed to generate *θ. According to the general gradient method, the updating equation for minimizing the objective function J is given by(1)()n n Jθθηθ+∂⎛=+⎜⎞⎟∂⎝⎠ (7)Where η is the learning rate and is the iteration step.n The proposed method KMD-opt is summarized as follows:Step 1. Set the learning rate η and the maximum iteration number N , and set ε to a very small positive number.Step 2. Initialize the kernel parameters (0)θθ= and set the iteration step .0n =Step 3. Update the kernel parameters ()n θ using Eq. (7).Step 4. If (1)()||n n θθ+ε−< or , stop. Otherwise, set n N ≥1n n =+, goto Step 3.4. ExperimentsThis section evaluates the effectiveness of the proposed KMD-opt method. For comparison, the MD and KMD are also tested. An artificial data set Circles , as shown in Fig. 1, and two real-world data sets Bupa and Pid from UCI Machine Learning Repository [5] are used. For each data set, half of data are used as the training data set, while the remaining data are used as the test data set. The kernel used in the experiments is the Gaussian kernel 22||||(,)exp 2x y K x y σ⎛⎞−=⎜⎟⎝⎠, where σ is the kernel parameter that should be optimized. In this paper, if without explicitexplanations, the initial value for the kernel parameter σis set to 0σ=, where x is the centroid of the total l training data. Specifically, the 0σ values for Circles ,Bupa and Pid are 2.33, 17.26 and 43.48 respectively. The learning rate η is set to 0.05 and ε is set to 0.0001 without extra explanations.Table 1 shows the test accuracies of MD, KMD and KMD-opt. The σ values are also presented. Table 1 shows that in most cases KMD obtains better test accuracy than MD, but when the kernel parameter is not chosen appropriately its performance deteriorates greatly. In all cases,KMD-opt achieves the best test accuracy. What is more, from Table 1, it can be found the KMD-opt method is quite robust because on every data set, the final σs it produced are almost with the same value although the method is with different initializations.As an example, the left part of Fig. 2 plots the test accuracy of KMD under a series of σvalues on Bupa. It verifies the claim that a good performance of KMD greatly depends on the selection of kernel parameters. The right part of Fig. 2 plots the objective function in Eq. (5) under a series of σ values on Bupa. It can be seen from Fig. 2 that the objective function reaches its minimum at similar σvalues as those at which KMD achieves its highest accuracy.5. ConclusionsIn this paper, a novel approach for learning the kernel parameters is proposed and successfully applied to the kernel minimum distance (KMD) classifier. An objective function is defined to measure the classification reliability of KMD with different kernel parameters, and then the optimal values of the kernel parameters are obtained by optimizing the objective function. Experiments show the effect of the proposed approach on learning kernel parameters in KMD. In future works, the proposed approach will be extended for other kernel-based learning methods such as support vector machine (SVM) and kernel fisher discriminate (KFD).References[1]J. Peng, D.R. Heisterkamp, H.K. Dai, Adaptive quasiconformal kernel nearest neighborclassification, IEEE Trans. PAMI 26 (5) (2004) 656-661.[2]J. Shawe-Taylor, N. Cristianini, Kernel methods for pattern analysis, Cambridge UniversityPress, 2004.[3]L. Wang, K.L. Chan, Learning kernel parameters by using class separability measure,NIPS’02 Workshop on Kernel Machines, Canada, 2002.[4] D.Q. Zhang, S.C. Chen, Clustering incomplete data using kernel-based fuzzy c-meansalgorithm, Neural Processing Letters 18(3) (2003) 155-162.[5] C. Blake, E. Keogh, and C.J. Merz, UCI repository of machine learning databases[/~mlearn/MLRepository.html], Department of Information and Computer Science, University of California, Irvine, CA, 1998.Fig. 1. The Circles data setFig. 2. Test accuracy (left) and objective function values (right) under a series of σ values onBupa .Table 1. Comparisons of test accuracy (%) of MD, KMD and KMD-opt (the values in the brackets denote the σ values at convergence).KMD KMD-opt DatasetsMD 0σ 20σ 30σ 0σ/20σ/30σ 20σ 30σ 0σ/2 0σ/3 Circles50 100 98 50 100 100 100(3.43) 100(3.43) 100(3.43) 100(3.43) 100(3.43) Bupa59.43 68 61.14 57.14 66.29 65.14 69.14(16.55)69.14(16.55)69.14(16.55)69.14(16.54) 69.14(16.54)Pid 62.5 65.1 58.07 50.78 64.32 64.84 65.63(41.45)65.63(41.45)65.63(41.45)65.63(41.45) 65.63(41.45)。